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