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 }