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, size_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->fg = fg; 71 72 if (op->out == NULL) 73 op->outlen = op->inlen; 74 return (op); 75 } 76 77 int 78 cryptotest_close_session(CK_SESSION_HANDLE hsession) 79 { 80 CK_RV rv; 81 rv = C_CloseSession(hsession); 82 if (rv != CKR_OK) 83 cryptotest_error("cryptotest_close_session", rv); 84 85 return (rv); 86 } 87 88 int 89 cryptotest_close(crypto_op_t *op) 90 { 91 (void) C_DestroyObject(op->hsession, op->keyt); 92 if (op->hsession != CK_INVALID_HANDLE) 93 (void) cryptotest_close_session(op->hsession); 94 free(op); 95 return (C_Finalize(NULL)); 96 } 97 98 int 99 get_mech_info(crypto_op_t *op) 100 { 101 CK_RV rv; 102 rv = pkcs11_str2mech(op->mechname, &op->mech); 103 if (rv != CKR_OK) { 104 cryptotest_error("get_mech_info", rv); 105 (void) fprintf(stderr, "failed to resolve mechanism name %s\n", 106 op->mechname); 107 (void) cryptotest_close(op); 108 return (CTEST_NAME_RESOLVE_FAILED); 109 } 110 return (rv); 111 } 112 113 114 int 115 get_hsession_by_mech(crypto_op_t *op) 116 { 117 CK_RV rv; 118 rv = SUNW_C_GetMechSession(op->mech, &op->hsession); 119 if (rv != CKR_OK) { 120 cryptotest_error("get_hsession_by_mech", rv); 121 (void) fprintf(stderr, 122 "could not find provider for mechanism %lu\n", 123 op->mech); 124 (void) cryptotest_close(op); 125 return (CTEST_MECH_NO_PROVIDER); 126 } 127 return (rv); 128 } 129 130 /* 131 * SIGN_* functions 132 */ 133 int 134 sign_init(crypto_op_t *op) 135 { 136 CK_MECHANISM mech; 137 CK_RV rv; 138 139 mech.mechanism = op->mech; 140 mech.pParameter = NULL; 141 mech.ulParameterLen = 0; 142 143 rv = SUNW_C_KeyToObject(op->hsession, op->mech, 144 op->key, op->keylen, &op->keyt); 145 146 if (rv != CKR_OK) 147 cryptotest_error("SUNW_C_KeyToObject", rv); 148 149 rv = C_SignInit(op->hsession, &mech, op->keyt); 150 151 if (rv != CKR_OK) 152 cryptotest_error("C_SignInit", rv); 153 154 return (rv); 155 } 156 157 int 158 sign_single(crypto_op_t *op) 159 { 160 CK_RV rv; 161 162 rv = C_Sign(op->hsession, op->in, op->inlen, 163 op->out, (CK_ULONG_PTR)&op->outlen); 164 if (rv != CKR_OK) 165 cryptotest_error("C_Sign", rv); 166 return (rv); 167 } 168 169 int 170 sign_update(crypto_op_t *op, int offset) 171 { 172 CK_RV rv; 173 rv = C_SignUpdate(op->hsession, op->in + offset, op->updatelen); 174 if (rv != CKR_OK) 175 cryptotest_error("C_SignUpdate", rv); 176 177 return (rv); 178 } 179 180 int 181 sign_final(crypto_op_t *op) 182 { 183 CK_RV rv; 184 rv = C_SignFinal(op->hsession, op->out, (CK_ULONG_PTR)&op->outlen); 185 if (rv != CKR_OK) 186 cryptotest_error("C_SignFinal", rv); 187 return (rv); 188 } 189 190 /* 191 * MAC_* functions 192 */ 193 int 194 mac_init(crypto_op_t *op) 195 { 196 return (sign_init(op)); 197 } 198 199 int 200 mac_single(crypto_op_t *op) 201 { 202 return (sign_single(op)); 203 } 204 205 int 206 mac_update(crypto_op_t *op, int offset) 207 { 208 return (sign_update(op, offset)); 209 } 210 211 int 212 mac_final(crypto_op_t *op) 213 { 214 return (sign_final(op)); 215 } 216 217 /* 218 * VERIFY_* functions 219 */ 220 int 221 verify_init(crypto_op_t *op) 222 { 223 CK_MECHANISM mech; 224 CK_RV rv; 225 226 mech.mechanism = op->mech; 227 mech.pParameter = NULL; 228 mech.ulParameterLen = 0; 229 230 rv = SUNW_C_KeyToObject(op->hsession, op->mech, 231 op->key, op->keylen, &op->keyt); 232 233 if (rv != CKR_OK) 234 cryptotest_error("SUNW_C_KeyToObject", rv); 235 236 rv = C_VerifyInit(op->hsession, &mech, op->keyt); 237 238 if (rv != CKR_OK) 239 cryptotest_error("C_VerifyInit", rv); 240 241 return (rv); 242 } 243 244 int 245 verify_single(crypto_op_t *op) 246 { 247 CK_RV rv; 248 249 rv = C_Verify(op->hsession, op->in, op->inlen, op->out, op->outlen); 250 if (rv != CKR_OK && rv != CKR_SIGNATURE_INVALID && 251 rv != CKR_SIGNATURE_LEN_RANGE) 252 cryptotest_error("C_Verify", rv); 253 return (rv); 254 } 255 256 int 257 verify_update(crypto_op_t *op, int offset) 258 { 259 CK_RV rv; 260 rv = C_VerifyUpdate(op->hsession, op->in + offset, op->updatelen); 261 if (rv != CKR_OK) 262 cryptotest_error("C_VerifyUpdate", rv); 263 return (rv); 264 } 265 266 int 267 verify_final(crypto_op_t *op) 268 { 269 CK_RV rv; 270 rv = C_VerifyFinal(op->hsession, op->out, op->outlen); 271 if (rv != CKR_OK && rv != CKR_SIGNATURE_INVALID && 272 rv != CKR_SIGNATURE_LEN_RANGE) 273 cryptotest_error("C_VerifyFinal", rv); 274 return (rv); 275 } 276 277 /* 278 * ENCRYPT_* functions 279 */ 280 int 281 encrypt_init(crypto_op_t *op) 282 { 283 CK_MECHANISM mech; 284 CK_RV rv; 285 286 mech.mechanism = op->mech; 287 mech.pParameter = op->param; 288 mech.ulParameterLen = op->paramlen; 289 290 rv = SUNW_C_KeyToObject(op->hsession, op->mech, 291 op->key, op->keylen, &op->keyt); 292 293 if (rv != CKR_OK) 294 cryptotest_error("SUNW_C_KeyToObject", rv); 295 296 rv = C_EncryptInit(op->hsession, &mech, op->keyt); 297 298 if (rv != CKR_OK) 299 cryptotest_error("C_EncryptInit", rv); 300 301 return (rv); 302 } 303 304 int 305 encrypt_single(crypto_op_t *op) 306 { 307 CK_RV rv; 308 309 rv = C_Encrypt(op->hsession, op->in, op->inlen, 310 op->out, (CK_ULONG_PTR)&op->outlen); 311 if (rv != CKR_OK) 312 cryptotest_error("C_Encrypt", rv); 313 return (rv); 314 } 315 316 int 317 encrypt_update(crypto_op_t *op, int offset, size_t *encrlen) 318 { 319 CK_RV rv; 320 CK_ULONG outlen = op->outlen - *encrlen; 321 rv = C_EncryptUpdate(op->hsession, op->in + offset, op->updatelen, 322 op->out + *encrlen, &outlen); 323 if (rv != CKR_OK) 324 cryptotest_error("C_EncryptUpdate", rv); 325 326 *encrlen += outlen; 327 return (rv); 328 } 329 330 int 331 encrypt_final(crypto_op_t *op, size_t encrlen) 332 { 333 CK_RV rv; 334 CK_ULONG outlen = op->outlen - encrlen; 335 rv = C_EncryptFinal(op->hsession, op->out + encrlen, &outlen); 336 if (rv != CKR_OK) 337 cryptotest_error("C_EncryptFinal", rv); 338 return (rv); 339 } 340 341 /* 342 * DECRYPT_* functions 343 */ 344 int 345 decrypt_init(crypto_op_t *op) 346 { 347 CK_MECHANISM mech; 348 CK_RV rv; 349 350 mech.mechanism = op->mech; 351 mech.pParameter = op->param; 352 mech.ulParameterLen = op->paramlen; 353 354 rv = SUNW_C_KeyToObject(op->hsession, op->mech, 355 op->key, op->keylen, &op->keyt); 356 357 if (rv != CKR_OK) 358 cryptotest_error("SUNW_C_KeyToObject", rv); 359 360 rv = C_DecryptInit(op->hsession, &mech, op->keyt); 361 362 if (rv != CKR_OK) 363 cryptotest_error("C_DecryptInit", rv); 364 365 return (rv); 366 } 367 368 int 369 decrypt_single(crypto_op_t *op) 370 { 371 CK_RV rv; 372 373 rv = C_Decrypt(op->hsession, op->in, op->inlen, 374 op->out, (CK_ULONG_PTR)&op->outlen); 375 if (rv != CKR_OK) 376 cryptotest_error("C_Decrypt", rv); 377 return (rv); 378 } 379 380 int 381 decrypt_update(crypto_op_t *op, int offset, size_t *encrlen) 382 { 383 CK_RV rv; 384 CK_ULONG outlen = op->outlen - *encrlen; 385 rv = C_DecryptUpdate(op->hsession, op->in + offset, op->updatelen, 386 op->out + *encrlen, &outlen); 387 if (rv != CKR_OK) 388 cryptotest_error("C_DecryptUpdate", rv); 389 390 *encrlen += outlen; 391 return (rv); 392 } 393 394 int 395 decrypt_final(crypto_op_t *op, size_t encrlen) 396 { 397 CK_RV rv; 398 CK_ULONG outlen = op->outlen - encrlen; 399 rv = C_DecryptFinal(op->hsession, op->out + encrlen, &outlen); 400 if (rv != CKR_OK) 401 cryptotest_error("C_DecryptFinal", rv); 402 return (rv); 403 }