1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2015 Nexenta Systems, Inc. All rights reserved. 14 * Copyright 2018, Joyent, Inc. 15 */ 16 17 #include <stdio.h> 18 #include <cryptoutil.h> 19 #include <security/cryptoki.h> 20 21 #include "cryptotest.h" 22 23 struct crypto_op { 24 CK_BYTE_PTR in; 25 CK_BYTE_PTR out; 26 CK_BYTE_PTR key; 27 CK_BYTE_PTR param; 28 29 size_t inlen; 30 size_t outlen; 31 size_t keylen; 32 size_t paramlen; 33 size_t updatelen; 34 35 char *mechname; 36 37 /* internal */ 38 CK_MECHANISM_TYPE mech; 39 CK_OBJECT_HANDLE keyt; 40 CK_SESSION_HANDLE hsession; 41 size_t fg; 42 }; 43 44 static void 45 cryptotest_error(char *name, CK_RV rv) 46 { 47 (void) fprintf(stderr, "%s: Error = 0x%.8lX '%s'\n", 48 name, rv, pkcs11_strerror(rv)); 49 } 50 51 crypto_op_t * 52 cryptotest_init(cryptotest_t *arg, crypto_func_group_t fg) 53 { 54 crypto_op_t *op = malloc(sizeof (*op)); 55 56 op->in = (CK_BYTE_PTR)arg->in; 57 op->out = (CK_BYTE_PTR)arg->out; 58 op->key = (CK_BYTE_PTR)arg->key; 59 op->param = (CK_BYTE_PTR)arg->param; 60 61 op->inlen = arg->inlen; 62 op->outlen = arg->outlen; 63 op->keylen = arg->keylen; 64 op->paramlen = arg->plen; 65 op->updatelen = arg->updatelen; 66 67 op->mechname = arg->mechname; 68 69 op->hsession = CK_INVALID_HANDLE; 70 op->keyt = CK_INVALID_HANDLE; 71 op->fg = fg; 72 73 if (op->out == NULL) 74 op->outlen = op->inlen; 75 return (op); 76 } 77 78 int 79 cryptotest_close_session(CK_SESSION_HANDLE hsession) 80 { 81 CK_RV rv; 82 rv = C_CloseSession(hsession); 83 if (rv != CKR_OK) 84 cryptotest_error("cryptotest_close_session", rv); 85 86 return (rv); 87 } 88 89 int 90 cryptotest_close(crypto_op_t *op) 91 { 92 if (op->keyt != CK_INVALID_HANDLE) 93 (void) C_DestroyObject(op->hsession, op->keyt); 94 95 if (op->hsession != CK_INVALID_HANDLE) 96 (void) cryptotest_close_session(op->hsession); 97 free(op); 98 return (C_Finalize(NULL)); 99 } 100 101 int 102 get_mech_info(crypto_op_t *op) 103 { 104 CK_RV rv; 105 rv = pkcs11_str2mech(op->mechname, &op->mech); 106 if (rv != CKR_OK) { 107 cryptotest_error("get_mech_info", rv); 108 (void) fprintf(stderr, "failed to resolve mechanism name %s\n", 109 op->mechname); 110 return (CTEST_NAME_RESOLVE_FAILED); 111 } 112 return (rv); 113 } 114 115 116 int 117 get_hsession_by_mech(crypto_op_t *op) 118 { 119 CK_RV rv; 120 rv = SUNW_C_GetMechSession(op->mech, &op->hsession); 121 if (rv != CKR_OK) { 122 cryptotest_error("get_hsession_by_mech", rv); 123 (void) fprintf(stderr, 124 "could not find provider for mechanism %lu\n", 125 op->mech); 126 return (CTEST_MECH_NO_PROVIDER); 127 } 128 return (rv); 129 } 130 131 /* 132 * SIGN_* functions 133 */ 134 int 135 sign_init(crypto_op_t *op) 136 { 137 CK_MECHANISM mech; 138 CK_RV rv; 139 140 mech.mechanism = op->mech; 141 mech.pParameter = NULL; 142 mech.ulParameterLen = 0; 143 144 rv = SUNW_C_KeyToObject(op->hsession, op->mech, 145 op->key, op->keylen, &op->keyt); 146 147 if (rv != CKR_OK) 148 cryptotest_error("SUNW_C_KeyToObject", rv); 149 150 rv = C_SignInit(op->hsession, &mech, op->keyt); 151 152 if (rv != CKR_OK) 153 cryptotest_error("C_SignInit", rv); 154 155 return (rv); 156 } 157 158 int 159 sign_single(crypto_op_t *op) 160 { 161 CK_RV rv; 162 163 rv = C_Sign(op->hsession, op->in, op->inlen, 164 op->out, (CK_ULONG_PTR)&op->outlen); 165 if (rv != CKR_OK) 166 cryptotest_error("C_Sign", rv); 167 return (rv); 168 } 169 170 int 171 sign_update(crypto_op_t *op, int offset) 172 { 173 CK_RV rv; 174 rv = C_SignUpdate(op->hsession, op->in + offset, op->updatelen); 175 if (rv != CKR_OK) 176 cryptotest_error("C_SignUpdate", rv); 177 178 return (rv); 179 } 180 181 int 182 sign_final(crypto_op_t *op) 183 { 184 CK_RV rv; 185 rv = C_SignFinal(op->hsession, op->out, (CK_ULONG_PTR)&op->outlen); 186 if (rv != CKR_OK) 187 cryptotest_error("C_SignFinal", rv); 188 return (rv); 189 } 190 191 /* 192 * MAC_* functions 193 */ 194 int 195 mac_init(crypto_op_t *op) 196 { 197 return (sign_init(op)); 198 } 199 200 int 201 mac_single(crypto_op_t *op) 202 { 203 return (sign_single(op)); 204 } 205 206 int 207 mac_update(crypto_op_t *op, int offset) 208 { 209 return (sign_update(op, offset)); 210 } 211 212 int 213 mac_final(crypto_op_t *op) 214 { 215 return (sign_final(op)); 216 } 217 218 /* 219 * VERIFY_* functions 220 */ 221 int 222 verify_init(crypto_op_t *op) 223 { 224 CK_MECHANISM mech; 225 CK_RV rv; 226 227 mech.mechanism = op->mech; 228 mech.pParameter = NULL; 229 mech.ulParameterLen = 0; 230 231 rv = SUNW_C_KeyToObject(op->hsession, op->mech, 232 op->key, op->keylen, &op->keyt); 233 234 if (rv != CKR_OK) 235 cryptotest_error("SUNW_C_KeyToObject", rv); 236 237 rv = C_VerifyInit(op->hsession, &mech, op->keyt); 238 239 if (rv != CKR_OK) 240 cryptotest_error("C_VerifyInit", rv); 241 242 return (rv); 243 } 244 245 int 246 verify_single(crypto_op_t *op) 247 { 248 CK_RV rv; 249 250 rv = C_Verify(op->hsession, op->in, op->inlen, op->out, op->outlen); 251 if (rv != CKR_OK && rv != CKR_SIGNATURE_INVALID && 252 rv != CKR_SIGNATURE_LEN_RANGE) 253 cryptotest_error("C_Verify", rv); 254 return (rv); 255 } 256 257 int 258 verify_update(crypto_op_t *op, int offset) 259 { 260 CK_RV rv; 261 rv = C_VerifyUpdate(op->hsession, op->in + offset, op->updatelen); 262 if (rv != CKR_OK) 263 cryptotest_error("C_VerifyUpdate", rv); 264 return (rv); 265 } 266 267 int 268 verify_final(crypto_op_t *op) 269 { 270 CK_RV rv; 271 rv = C_VerifyFinal(op->hsession, op->out, op->outlen); 272 if (rv != CKR_OK && rv != CKR_SIGNATURE_INVALID && 273 rv != CKR_SIGNATURE_LEN_RANGE) 274 cryptotest_error("C_VerifyFinal", rv); 275 return (rv); 276 } 277 278 /* 279 * ENCRYPT_* functions 280 */ 281 int 282 encrypt_init(crypto_op_t *op) 283 { 284 CK_MECHANISM mech; 285 CK_RV rv; 286 287 mech.mechanism = op->mech; 288 mech.pParameter = op->param; 289 mech.ulParameterLen = op->paramlen; 290 291 rv = SUNW_C_KeyToObject(op->hsession, op->mech, 292 op->key, op->keylen, &op->keyt); 293 294 if (rv != CKR_OK) 295 cryptotest_error("SUNW_C_KeyToObject", rv); 296 297 rv = C_EncryptInit(op->hsession, &mech, op->keyt); 298 299 if (rv != CKR_OK) 300 cryptotest_error("C_EncryptInit", rv); 301 302 return (rv); 303 } 304 305 int 306 encrypt_single(crypto_op_t *op) 307 { 308 CK_RV rv; 309 310 rv = C_Encrypt(op->hsession, op->in, op->inlen, 311 op->out, (CK_ULONG_PTR)&op->outlen); 312 if (rv != CKR_OK) 313 cryptotest_error("C_Encrypt", rv); 314 return (rv); 315 } 316 317 int 318 encrypt_update(crypto_op_t *op, int offset, size_t *encrlen) 319 { 320 CK_RV rv; 321 CK_ULONG outlen = op->outlen - *encrlen; 322 rv = C_EncryptUpdate(op->hsession, op->in + offset, op->updatelen, 323 op->out + *encrlen, &outlen); 324 if (rv != CKR_OK) 325 cryptotest_error("C_EncryptUpdate", rv); 326 327 *encrlen += outlen; 328 return (rv); 329 } 330 331 int 332 encrypt_final(crypto_op_t *op, size_t encrlen) 333 { 334 CK_RV rv; 335 CK_ULONG outlen = op->outlen - encrlen; 336 rv = C_EncryptFinal(op->hsession, op->out + encrlen, &outlen); 337 if (rv != CKR_OK) 338 cryptotest_error("C_EncryptFinal", rv); 339 return (rv); 340 } 341 342 /* 343 * DECRYPT_* functions 344 */ 345 int 346 decrypt_init(crypto_op_t *op) 347 { 348 CK_MECHANISM mech; 349 CK_RV rv; 350 351 mech.mechanism = op->mech; 352 mech.pParameter = op->param; 353 mech.ulParameterLen = op->paramlen; 354 355 rv = SUNW_C_KeyToObject(op->hsession, op->mech, 356 op->key, op->keylen, &op->keyt); 357 358 if (rv != CKR_OK) 359 cryptotest_error("SUNW_C_KeyToObject", rv); 360 361 rv = C_DecryptInit(op->hsession, &mech, op->keyt); 362 363 if (rv != CKR_OK) 364 cryptotest_error("C_DecryptInit", rv); 365 366 return (rv); 367 } 368 369 int 370 decrypt_single(crypto_op_t *op) 371 { 372 CK_RV rv; 373 374 rv = C_Decrypt(op->hsession, op->in, op->inlen, 375 op->out, (CK_ULONG_PTR)&op->outlen); 376 if (rv != CKR_OK) 377 cryptotest_error("C_Decrypt", rv); 378 return (rv); 379 } 380 381 int 382 decrypt_update(crypto_op_t *op, int offset, size_t *encrlen) 383 { 384 CK_RV rv; 385 CK_ULONG outlen = op->outlen - *encrlen; 386 rv = C_DecryptUpdate(op->hsession, op->in + offset, op->updatelen, 387 op->out + *encrlen, &outlen); 388 if (rv != CKR_OK) 389 cryptotest_error("C_DecryptUpdate", rv); 390 391 *encrlen += outlen; 392 return (rv); 393 } 394 395 int 396 decrypt_final(crypto_op_t *op, size_t encrlen) 397 { 398 CK_RV rv; 399 CK_ULONG outlen = op->outlen - encrlen; 400 rv = C_DecryptFinal(op->hsession, op->out + encrlen, &outlen); 401 if (rv != CKR_OK) 402 cryptotest_error("C_DecryptFinal", rv); 403 return (rv); 404 } 405 406 /* 407 * DIGEST_ functions 408 */ 409 int 410 digest_init(crypto_op_t *op) 411 { 412 CK_MECHANISM mech; 413 CK_RV rv; 414 415 mech.mechanism = op->mech; 416 mech.pParameter = op->param; 417 mech.ulParameterLen = op->paramlen; 418 419 rv = C_DigestInit(op->hsession, &mech); 420 if (rv != CKR_OK) 421 cryptotest_error("C_DigestInit", rv); 422 return (rv); 423 } 424 425 int 426 digest_single(crypto_op_t *op) 427 { 428 CK_RV rv; 429 430 rv = C_Digest(op->hsession, op->in, op->inlen, 431 op->out, (CK_ULONG_PTR)&op->outlen); 432 if (rv != CKR_OK) 433 cryptotest_error("C_Digest", rv); 434 return (rv); 435 } 436 437 int 438 digest_update(crypto_op_t *op, int offset) 439 { 440 CK_RV rv; 441 442 rv = C_DigestUpdate(op->hsession, op->in + offset, op->updatelen); 443 if (rv != CKR_OK) 444 cryptotest_error("C_DigestUpdate", rv); 445 return (rv); 446 } 447 448 int 449 digest_final(crypto_op_t *op) 450 { 451 CK_RV rv; 452 453 rv = C_DigestFinal(op->hsession, op->out, (CK_ULONG_PTR)&op->outlen); 454 if (rv != CKR_OK) 455 cryptotest_error("C_DigestFinal", rv); 456 return (rv); 457 } 458 459 void 460 ccm_init_params(void *buf, ulong_t ulDataLen, uchar_t *pNonce, 461 ulong_t ulNonceLen, uchar_t *pAAD, ulong_t ulAADLen, ulong_t ulMACLen) 462 { 463 CK_CCM_PARAMS *pp = buf; 464 465 pp->ulDataLen = ulDataLen; 466 pp->pNonce = pNonce; 467 pp->ulNonceLen = ulNonceLen; 468 pp->pAAD = pAAD; 469 pp->ulAADLen = ulAADLen; 470 pp->ulMACLen = ulMACLen; 471 } 472 473 size_t 474 ccm_param_len(void) 475 { 476 return (sizeof (CK_CCM_PARAMS)); 477 } 478