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 }