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