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