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