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 2016 Nexenta Systems, Inc.  All rights reserved.
  14  * Copyright 2018, Joyent, Inc.
  15  */
  16 
  17 #define __EXTENSIONS__
  18 #include <strings.h>
  19 #include <stdlib.h>
  20 #include <stdio.h>
  21 #include "cryptotest.h"
  22 
  23 
  24 
  25 test_fg_t cryptotest_decr_fg = {test_decrypt_single, test_decrypt};
  26 test_fg_t cryptotest_encr_fg = {test_encrypt_single, test_encrypt};
  27 test_fg_t cryptotest_mac_fg = {test_mac_single, test_mac};
  28 test_fg_t cryptotest_digest_fg = {test_digest_single, test_digest};
  29 
  30 /*
  31  * Utils
  32  */
  33 
  34 void
  35 printbuf(uint8_t *buf, char *name, size_t size)
  36 {
  37         size_t i;
  38 
  39         flockfile(stderr);
  40         (void) fprintf(stderr, "%s%s", name, (size > 0) ? " " : "");
  41         for (i = 0; i < size; i++)
  42                 (void) fprintf(stderr, "%02x", buf[i]);
  43         (void) fputc('\n', stderr);
  44         funlockfile(stderr);
  45 }
  46 
  47 int
  48 bufcmp(uint8_t *auth, uint8_t *cmp, size_t size)
  49 {
  50         if (memcmp(cmp, auth, size) != 0) {
  51                 (void) fprintf(stderr, "mismatched result\n\n");
  52                 printbuf(cmp, "calc", size);
  53                 printbuf(auth, "orig", size);
  54                 return (1);
  55         } else {
  56                 (void) fprintf(stderr, "result matches\n\n");
  57                 return (0);
  58         }
  59 }
  60 
  61 /*
  62  * Wrapper functions
  63  */
  64 
  65 int
  66 run_test(cryptotest_t *args, uint8_t *cmp, size_t cmplen,
  67     test_fg_t *funcs)
  68 {
  69         int ret, errs = 0;
  70         static int i = 0;
  71 
  72         (void) fprintf(stderr, "%s: run %d\n", args->mechname, ++i);
  73         bzero(args->out, args->outlen);
  74         ret = funcs->update(args);
  75         if (ret > 0) {
  76                 (void) fprintf(stderr, "failure %x\n", ret);
  77                 errs += 1;
  78         } else if (ret < 0) {
  79                 (void) fprintf(stderr, "fatal error %d\n", ret);
  80                 exit(1);
  81         } else
  82                 errs += bufcmp(cmp, args->out, cmplen);
  83 
  84         bzero(args->out, args->outlen);
  85         ret = funcs->single(args);
  86         if (ret > 0) {
  87                 (void) fprintf(stderr, "failure %x\n", ret);
  88                 errs += 1;
  89         } else if (ret < 0) {
  90                 (void) fprintf(stderr, "fatal error %d\n", ret);
  91                 exit(2);
  92         } else
  93                 errs += bufcmp(cmp, args->out, cmplen);
  94 
  95         return (errs);
  96 }
  97 
  98 static int
  99 test_mac_common(cryptotest_t *args, boolean_t AIO)
 100 {
 101         int ret, i;
 102         crypto_op_t *crypto_op;
 103 
 104         if (args->in == NULL || args->key == NULL)
 105                 return (CRYPTO_FAILED);
 106 
 107         if ((crypto_op = cryptotest_init(args, CRYPTO_FG_MAC)) == NULL) {
 108                 (void) fprintf(stderr, "Error occured during initialization\n");
 109                 (void) cryptotest_close(NULL);
 110                 return (CTEST_INIT_FAILED);
 111         }
 112 
 113         if ((ret = get_mech_info(crypto_op)) != CRYPTO_SUCCESS)
 114                 goto out;
 115 
 116         if ((ret = get_hsession_by_mech(crypto_op)) != CRYPTO_SUCCESS)
 117                 goto out;
 118 
 119         if ((ret = mac_init(crypto_op)) != CRYPTO_SUCCESS)
 120                 goto out;
 121 
 122         if (AIO) {
 123                 if ((ret = mac_single(crypto_op)) != CRYPTO_SUCCESS)
 124                         goto out;
 125         } else {
 126                 for (i = 0; i < args->inlen; i += args->updatelen) {
 127 
 128                         if ((ret = mac_update(crypto_op, i)) != CRYPTO_SUCCESS)
 129                                 goto out;
 130                 }
 131 
 132                 if ((ret = mac_final(crypto_op)) != CRYPTO_SUCCESS)
 133                         goto out;
 134 
 135         }
 136 
 137 out:
 138         (void) cryptotest_close(crypto_op);
 139         return (ret);
 140 }
 141 
 142 int
 143 test_mac_single(cryptotest_t *args)
 144 {
 145         return (test_mac_common(args, B_TRUE));
 146 }
 147 
 148 int
 149 test_mac(cryptotest_t *args)
 150 {
 151         return (test_mac_common(args, B_FALSE));
 152 }
 153 
 154 static int
 155 test_encrypt_common(cryptotest_t *args, boolean_t AIO)
 156 {
 157         int ret, i;
 158         size_t encrlen = 0;
 159         crypto_op_t *crypto_op;
 160 
 161         if (args->key == NULL)
 162                 return (CRYPTO_FAILED);
 163 
 164         if ((crypto_op = cryptotest_init(args, CRYPTO_FG_ENCRYPT)) == NULL) {
 165                 (void) fprintf(stderr, "Error occured during initialization\n");
 166                 (void) cryptotest_close(NULL);
 167                 return (CTEST_INIT_FAILED);
 168         }
 169 
 170         if ((ret = get_mech_info(crypto_op)) != CRYPTO_SUCCESS)
 171                 goto out;
 172 
 173         if ((ret = get_hsession_by_mech(crypto_op)) != CRYPTO_SUCCESS)
 174                 goto out;
 175 
 176         if ((ret = encrypt_init(crypto_op)) != CRYPTO_SUCCESS)
 177                 goto out;
 178 
 179         if (AIO) {
 180                 if ((ret = encrypt_single(crypto_op)) != CRYPTO_SUCCESS)
 181                         goto out;
 182         } else {
 183                 for (i = 0; i < args->inlen; i += args->updatelen) {
 184 
 185                         if ((ret = encrypt_update(crypto_op, i,
 186                             &encrlen)) != CRYPTO_SUCCESS)
 187                                 goto out;
 188                 }
 189 
 190                 if ((ret = encrypt_final(crypto_op, encrlen)) != CRYPTO_SUCCESS)
 191                         goto out;
 192 
 193         }
 194 
 195 out:
 196         (void) cryptotest_close(crypto_op);
 197         return (ret);
 198 }
 199 
 200 int
 201 test_encrypt_single(cryptotest_t *args)
 202 {
 203         return (test_encrypt_common(args, B_TRUE));
 204 }
 205 
 206 
 207 int
 208 test_encrypt(cryptotest_t *args)
 209 {
 210         return (test_encrypt_common(args, B_FALSE));
 211 }
 212 
 213 static int
 214 test_decrypt_common(cryptotest_t *args, boolean_t AIO)
 215 {
 216         int ret, i;
 217         size_t encrlen = 0;
 218         crypto_op_t *crypto_op;
 219 
 220         if (args->key == NULL)
 221                 return (CRYPTO_FAILED);
 222 
 223         if ((crypto_op = cryptotest_init(args, CRYPTO_FG_DECRYPT)) == NULL) {
 224                 (void) fprintf(stderr, "Error occured during initialization\n");
 225                 (void) cryptotest_close(NULL);
 226                 return (CTEST_INIT_FAILED);
 227         }
 228 
 229         if ((ret = get_mech_info(crypto_op)) != CRYPTO_SUCCESS)
 230                 goto out;
 231 
 232         if ((ret = get_hsession_by_mech(crypto_op)) != CRYPTO_SUCCESS)
 233                 goto out;
 234 
 235         if ((ret = decrypt_init(crypto_op)) != CRYPTO_SUCCESS)
 236                 goto out;
 237 
 238         if (AIO) {
 239                 if ((ret = decrypt_single(crypto_op)) != CRYPTO_SUCCESS)
 240                         goto out;
 241         } else {
 242                 for (i = 0; i < args->inlen; i += args->updatelen) {
 243 
 244                         if ((ret = decrypt_update(crypto_op, i,
 245                             &encrlen)) != CRYPTO_SUCCESS)
 246                                 goto out;
 247                 }
 248 
 249                 if ((ret = decrypt_final(crypto_op, encrlen)) != CRYPTO_SUCCESS)
 250                         goto out;
 251 
 252         }
 253 
 254 out:
 255         (void) cryptotest_close(crypto_op);
 256         return (ret);
 257 }
 258 
 259 int
 260 test_decrypt_single(cryptotest_t *args)
 261 {
 262         return (test_decrypt_common(args, B_TRUE));
 263 }
 264 
 265 
 266 int
 267 test_decrypt(cryptotest_t *args)
 268 {
 269         return (test_decrypt_common(args, B_FALSE));
 270 }
 271 
 272 static int
 273 test_digest_common(cryptotest_t *args, boolean_t AIO)
 274 {
 275         int ret, i;
 276         crypto_op_t *crypto_op;
 277 
 278         if ((crypto_op = cryptotest_init(args, CRYPTO_FG_DIGEST)) == NULL) {
 279                 (void) fprintf(stderr, "Error occured during initalization\n");
 280                 (void) cryptotest_close(NULL);
 281                 return (CTEST_INIT_FAILED);
 282         }
 283 
 284         if ((ret = get_mech_info(crypto_op)) != CRYPTO_SUCCESS)
 285                 goto out;
 286 
 287         if ((ret = get_hsession_by_mech(crypto_op)) != CRYPTO_SUCCESS)
 288                 goto out;
 289 
 290         if ((ret = digest_init(crypto_op)) != CRYPTO_SUCCESS)
 291                 goto out;
 292 
 293         if (AIO) {
 294                 if ((ret = digest_single(crypto_op)) != CRYPTO_SUCCESS)
 295                         goto out;
 296         } else {
 297                 for (i = 0; i < args->inlen; i += args->updatelen) {
 298 
 299                         if ((ret = digest_update(crypto_op, i)) !=
 300                             CRYPTO_SUCCESS)
 301                                 goto out;
 302                 }
 303 
 304                 if ((ret = digest_final(crypto_op)) != CRYPTO_SUCCESS)
 305                         goto out;
 306         }
 307 
 308 out:
 309         (void) cryptotest_close(crypto_op);
 310         return (ret);
 311 }
 312 
 313 int
 314 test_digest_single(cryptotest_t *args)
 315 {
 316         return (test_digest_common(args, B_TRUE));
 317 }
 318 
 319 int
 320 test_digest(cryptotest_t *args)
 321 {
 322         return (test_digest_common(args, B_FALSE));
 323 }