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                 return (CTEST_NAME_RESOLVE_FAILED);
 108         }
 109         return (rv);
 110 }
 111 
 112 
 113 int
 114 get_hsession_by_mech(crypto_op_t *op)
 115 {
 116         CK_RV rv;
 117         rv = SUNW_C_GetMechSession(op->mech, &op->hsession);
 118         if (rv != CKR_OK) {
 119                 cryptotest_error("get_hsession_by_mech", rv);
 120                 (void) fprintf(stderr,
 121                     "could not find provider for mechanism %lu\n",
 122                     op->mech);
 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 
 403 /*
 404  * DIGEST_ functions
 405  */
 406 int
 407 digest_init(crypto_op_t *op)
 408 {
 409         CK_MECHANISM mech;
 410         CK_RV rv;
 411 
 412         mech.mechanism = op->mech;
 413         mech.pParameter = op->param;
 414         mech.ulParameterLen = op->paramlen;
 415 
 416         rv = C_DigestInit(op->hsession, &mech);
 417         if (rv != CKR_OK)
 418                 cryptotest_error("C_DigestInit", rv);
 419         return (rv);
 420 }
 421 
 422 int
 423 digest_single(crypto_op_t *op)
 424 {
 425         CK_RV rv;
 426 
 427         rv = C_Digest(op->hsession, op->in, op->inlen,
 428             op->out, (CK_ULONG_PTR)&op->outlen);
 429         if (rv != CKR_OK)
 430                 cryptotest_error("C_Digest", rv);
 431         return (rv);
 432 }
 433 
 434 int
 435 digest_update(crypto_op_t *op, int offset)
 436 {
 437         CK_RV rv;
 438 
 439         rv = C_DigestUpdate(op->hsession, op->in + offset, op->updatelen);
 440         if (rv != CKR_OK)
 441                 cryptotest_error("C_DigestUpdate", rv);
 442         return (rv);
 443 }
 444 
 445 int
 446 digest_final(crypto_op_t *op)
 447 {
 448         CK_RV rv;
 449 
 450         rv = C_DigestFinal(op->hsession, op->out, (CK_ULONG_PTR)&op->outlen);
 451         if (rv != CKR_OK)
 452                 cryptotest_error("C_DigestFinal", rv);
 453         return (rv);
 454 }