Author: cem
Date: Mon Jul  9 07:28:13 2018
New Revision: 336125
URL: https://svnweb.freebsd.org/changeset/base/336125

Log:
  OCF: Add plain hash modes
  
  In part, to support OpenSSL's use of cryptodev, which puts the HMAC pieces
  in software and only offloads the raw hash primitive.
  
  The following cryptodev identifiers are added:
  
   * CRYPTO_RIPEMD160 (not hooked up)
   * CRYPTO_SHA2_224
   * CRYPTO_SHA2_256
   * CRYPTO_SHA2_384
   * CRYPTO_SHA2_512
  
  The plain SHA1 and 2 hashes are plumbed through cryptodev (feels like there
  is a lot of redundancy here...) and cryptosoft.
  
  This adds new auth_hash implementations for the plain hashes, as well as
  SHA1 (which had a cryptodev.h identifier, but no implementation).
  
  Add plain SHA 1 and 2 hash tests to the cryptocheck tool.
  
  Motivation stems from John Baldwin's earlier OCF email,
  https://lists.freebsd.org/pipermail/freebsd-arch/2018-January/018835.html .

Modified:
  head/sys/opencrypto/cryptodev.c
  head/sys/opencrypto/cryptodev.h
  head/sys/opencrypto/cryptosoft.c
  head/sys/opencrypto/xform_auth.h
  head/sys/opencrypto/xform_sha1.c
  head/sys/opencrypto/xform_sha2.c
  head/tools/tools/crypto/cryptocheck.c

Modified: head/sys/opencrypto/cryptodev.c
==============================================================================
--- head/sys/opencrypto/cryptodev.c     Mon Jul  9 07:26:12 2018        
(r336124)
+++ head/sys/opencrypto/cryptodev.c     Mon Jul  9 07:28:13 2018        
(r336125)
@@ -489,10 +489,23 @@ cryptof_ioctl(
                case CRYPTO_MD5:
                        thash = &auth_hash_md5;
                        break;
+#endif
                case CRYPTO_SHA1:
                        thash = &auth_hash_sha1;
                        break;
-#endif
+               case CRYPTO_SHA2_224:
+                       thash = &auth_hash_sha2_224;
+                       break;
+               case CRYPTO_SHA2_256:
+                       thash = &auth_hash_sha2_256;
+                       break;
+               case CRYPTO_SHA2_384:
+                       thash = &auth_hash_sha2_384;
+                       break;
+               case CRYPTO_SHA2_512:
+                       thash = &auth_hash_sha2_512;
+                       break;
+
                case CRYPTO_NULL_HMAC:
                        thash = &auth_hash_null;
                        break;

Modified: head/sys/opencrypto/cryptodev.h
==============================================================================
--- head/sys/opencrypto/cryptodev.h     Mon Jul  9 07:26:12 2018        
(r336124)
+++ head/sys/opencrypto/cryptodev.h     Mon Jul  9 07:28:13 2018        
(r336125)
@@ -186,7 +186,12 @@
 #define        CRYPTO_BLAKE2S          30 /* Blake2s hash */
 #define        CRYPTO_CHACHA20         31 /* Chacha20 stream cipher */
 #define        CRYPTO_SHA2_224_HMAC    32
-#define        CRYPTO_ALGORITHM_MAX    32 /* Keep updated - see below */
+#define        CRYPTO_RIPEMD160        33
+#define        CRYPTO_SHA2_224         34
+#define        CRYPTO_SHA2_256         35
+#define        CRYPTO_SHA2_384         36
+#define        CRYPTO_SHA2_512         37
+#define        CRYPTO_ALGORITHM_MAX    37 /* Keep updated - see below */
 
 #define        CRYPTO_ALGO_VALID(x)    ((x) >= CRYPTO_ALGORITHM_MIN && \
                                 (x) <= CRYPTO_ALGORITHM_MAX)

Modified: head/sys/opencrypto/cryptosoft.c
==============================================================================
--- head/sys/opencrypto/cryptosoft.c    Mon Jul  9 07:26:12 2018        
(r336124)
+++ head/sys/opencrypto/cryptosoft.c    Mon Jul  9 07:28:13 2018        
(r336125)
@@ -421,6 +421,14 @@ swcr_authcompute(struct cryptodesc *crd, struct swcr_d
                return err;
 
        switch (sw->sw_alg) {
+       case CRYPTO_SHA1:
+       case CRYPTO_SHA2_224:
+       case CRYPTO_SHA2_256:
+       case CRYPTO_SHA2_384:
+       case CRYPTO_SHA2_512:
+               axf->Final(aalg, &ctx);
+               break;
+
        case CRYPTO_MD5_HMAC:
        case CRYPTO_SHA1_HMAC:
        case CRYPTO_SHA2_224_HMAC:
@@ -934,9 +942,23 @@ swcr_newsession(device_t dev, u_int32_t *sid, struct c
                case CRYPTO_MD5:
                        axf = &auth_hash_md5;
                        goto auth3common;
+#endif
 
                case CRYPTO_SHA1:
                        axf = &auth_hash_sha1;
+                       goto auth3common;
+               case CRYPTO_SHA2_224:
+                       axf = &auth_hash_sha2_224;
+                       goto auth3common;
+               case CRYPTO_SHA2_256:
+                       axf = &auth_hash_sha2_256;
+                       goto auth3common;
+               case CRYPTO_SHA2_384:
+                       axf = &auth_hash_sha2_384;
+                       goto auth3common;
+               case CRYPTO_SHA2_512:
+                       axf = &auth_hash_sha2_512;
+
                auth3common:
                        (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
                            M_NOWAIT);
@@ -950,7 +972,6 @@ swcr_newsession(device_t dev, u_int32_t *sid, struct c
                        (*swd)->sw_mlen = cri->cri_mlen;
                        (*swd)->sw_axf = axf;
                        break;
-#endif
 
                case CRYPTO_AES_128_NIST_GMAC:
                        axf = &auth_hash_nist_gmac_aes_128;
@@ -1110,6 +1131,10 @@ swcr_freesession_locked(device_t dev, u_int64_t tid)
                case CRYPTO_BLAKE2S:
                case CRYPTO_MD5:
                case CRYPTO_SHA1:
+               case CRYPTO_SHA2_224:
+               case CRYPTO_SHA2_256:
+               case CRYPTO_SHA2_384:
+               case CRYPTO_SHA2_512:
                        axf = swd->sw_axf;
 
                        if (swd->sw_ictx) {
@@ -1216,6 +1241,10 @@ swcr_process(device_t dev, struct cryptop *crp, int hi
                case CRYPTO_SHA1_KPDK:
                case CRYPTO_MD5:
                case CRYPTO_SHA1:
+               case CRYPTO_SHA2_224:
+               case CRYPTO_SHA2_256:
+               case CRYPTO_SHA2_384:
+               case CRYPTO_SHA2_512:
                case CRYPTO_BLAKE2B:
                case CRYPTO_BLAKE2S:
                        if ((crp->crp_etype = swcr_authcompute(crd, sw,
@@ -1300,6 +1329,10 @@ swcr_attach(device_t dev)
        REGISTER(CRYPTO_SHA1_KPDK);
        REGISTER(CRYPTO_MD5);
        REGISTER(CRYPTO_SHA1);
+       REGISTER(CRYPTO_SHA2_224);
+       REGISTER(CRYPTO_SHA2_256);
+       REGISTER(CRYPTO_SHA2_384);
+       REGISTER(CRYPTO_SHA2_512);
        REGISTER(CRYPTO_RIJNDAEL128_CBC);
        REGISTER(CRYPTO_AES_XTS);
        REGISTER(CRYPTO_AES_ICM);

Modified: head/sys/opencrypto/xform_auth.h
==============================================================================
--- head/sys/opencrypto/xform_auth.h    Mon Jul  9 07:26:12 2018        
(r336124)
+++ head/sys/opencrypto/xform_auth.h    Mon Jul  9 07:28:13 2018        
(r336125)
@@ -73,6 +73,11 @@ extern struct auth_hash auth_hash_hmac_sha2_224;
 extern struct auth_hash auth_hash_hmac_sha2_256;
 extern struct auth_hash auth_hash_hmac_sha2_384;
 extern struct auth_hash auth_hash_hmac_sha2_512;
+extern struct auth_hash auth_hash_sha1;
+extern struct auth_hash auth_hash_sha2_224;
+extern struct auth_hash auth_hash_sha2_256;
+extern struct auth_hash auth_hash_sha2_384;
+extern struct auth_hash auth_hash_sha2_512;
 extern struct auth_hash auth_hash_nist_gmac_aes_128;
 extern struct auth_hash auth_hash_nist_gmac_aes_192;
 extern struct auth_hash auth_hash_nist_gmac_aes_256;

Modified: head/sys/opencrypto/xform_sha1.c
==============================================================================
--- head/sys/opencrypto/xform_sha1.c    Mon Jul  9 07:26:12 2018        
(r336124)
+++ head/sys/opencrypto/xform_sha1.c    Mon Jul  9 07:28:13 2018        
(r336125)
@@ -57,6 +57,18 @@ static       void SHA1Init_int(void *);
 static int SHA1Update_int(void *, const u_int8_t *, u_int16_t);
 static void SHA1Final_int(u_int8_t *, void *);
 
+/* Plain hash */
+struct auth_hash auth_hash_sha1 = {
+       .type = CRYPTO_SHA1,
+       .name = "SHA1",
+       .hashsize = SHA1_HASH_LEN,
+       .ctxsize = sizeof(SHA1_CTX),
+       .blocksize = SHA1_BLOCK_LEN,
+       .Init = SHA1Init_int,
+       .Update = SHA1Update_int,
+       .Final = SHA1Final_int,
+};
+
 /* Authentication instances */
 struct auth_hash auth_hash_hmac_sha1 = {
        .type = CRYPTO_SHA1_HMAC,

Modified: head/sys/opencrypto/xform_sha2.c
==============================================================================
--- head/sys/opencrypto/xform_sha2.c    Mon Jul  9 07:26:12 2018        
(r336124)
+++ head/sys/opencrypto/xform_sha2.c    Mon Jul  9 07:28:13 2018        
(r336125)
@@ -61,6 +61,54 @@ static       int SHA256Update_int(void *, const u_int8_t *, 
 static int SHA384Update_int(void *, const u_int8_t *, u_int16_t);
 static int SHA512Update_int(void *, const u_int8_t *, u_int16_t);
 
+/* Plain hashes */
+struct auth_hash auth_hash_sha2_224 = {
+       .type = CRYPTO_SHA2_224,
+       .name = "SHA2-224",
+       .hashsize = SHA2_224_HASH_LEN,
+       .ctxsize = sizeof(SHA224_CTX),
+       .blocksize = SHA2_224_BLOCK_LEN,
+       .Init = (void (*)(void *)) SHA224_Init,
+       .Update = SHA224Update_int,
+       .Final = (void (*)(u_int8_t *, void *)) SHA224_Final,
+};
+
+struct auth_hash auth_hash_sha2_256 = {
+       .type = CRYPTO_SHA2_256,
+       .name = "SHA2-256",
+       .keysize = SHA2_256_BLOCK_LEN,
+       .hashsize = SHA2_256_HASH_LEN,
+       .ctxsize = sizeof(SHA256_CTX),
+       .blocksize = SHA2_256_BLOCK_LEN,
+       .Init = (void (*)(void *)) SHA256_Init,
+       .Update = SHA256Update_int,
+       .Final = (void (*)(u_int8_t *, void *)) SHA256_Final,
+};
+
+struct auth_hash auth_hash_sha2_384 = {
+       .type = CRYPTO_SHA2_384,
+       .name = "SHA2-384",
+       .keysize = SHA2_384_BLOCK_LEN,
+       .hashsize = SHA2_384_HASH_LEN,
+       .ctxsize = sizeof(SHA384_CTX),
+       .blocksize = SHA2_384_BLOCK_LEN,
+       .Init = (void (*)(void *)) SHA384_Init,
+       .Update = SHA384Update_int,
+       .Final = (void (*)(u_int8_t *, void *)) SHA384_Final,
+};
+
+struct auth_hash auth_hash_sha2_512 = {
+       .type = CRYPTO_SHA2_512,
+       .name = "SHA2-512",
+       .keysize = SHA2_512_BLOCK_LEN,
+       .hashsize = SHA2_512_HASH_LEN,
+       .ctxsize = sizeof(SHA512_CTX),
+       .blocksize = SHA2_512_BLOCK_LEN,
+       .Init = (void (*)(void *)) SHA512_Init,
+       .Update = SHA512Update_int,
+       .Final = (void (*)(u_int8_t *, void *)) SHA512_Final,
+};
+
 /* Authentication instances */
 struct auth_hash auth_hash_hmac_sha2_224 = {
        .type = CRYPTO_SHA2_224_HMAC,

Modified: head/tools/tools/crypto/cryptocheck.c
==============================================================================
--- head/tools/tools/crypto/cryptocheck.c       Mon Jul  9 07:26:12 2018        
(r336124)
+++ head/tools/tools/crypto/cryptocheck.c       Mon Jul  9 07:28:13 2018        
(r336125)
@@ -131,20 +131,30 @@ struct alg {
        const char *name;
        int cipher;
        int mac;
-       enum { T_HMAC, T_BLKCIPHER, T_AUTHENC, T_GCM } type;
+       enum { T_HASH, T_HMAC, T_BLKCIPHER, T_AUTHENC, T_GCM } type;
        const EVP_CIPHER *(*evp_cipher)(void);
        const EVP_MD *(*evp_md)(void);
 } algs[] = {
-       { .name = "sha1", .mac = CRYPTO_SHA1_HMAC, .type = T_HMAC,
+       { .name = "sha1", .mac = CRYPTO_SHA1, .type = T_HASH,
          .evp_md = EVP_sha1 },
-       { .name = "sha224", .mac = CRYPTO_SHA2_224_HMAC, .type = T_HMAC,
+       { .name = "sha224", .mac = CRYPTO_SHA2_224, .type = T_HASH,
          .evp_md = EVP_sha224 },
-       { .name = "sha256", .mac = CRYPTO_SHA2_256_HMAC, .type = T_HMAC,
+       { .name = "sha256", .mac = CRYPTO_SHA2_256, .type = T_HASH,
          .evp_md = EVP_sha256 },
-       { .name = "sha384", .mac = CRYPTO_SHA2_384_HMAC, .type = T_HMAC,
+       { .name = "sha384", .mac = CRYPTO_SHA2_384, .type = T_HASH,
          .evp_md = EVP_sha384 },
-       { .name = "sha512", .mac = CRYPTO_SHA2_512_HMAC, .type = T_HMAC,
+       { .name = "sha512", .mac = CRYPTO_SHA2_512, .type = T_HASH,
          .evp_md = EVP_sha512 },
+       { .name = "sha1hmac", .mac = CRYPTO_SHA1_HMAC, .type = T_HMAC,
+         .evp_md = EVP_sha1 },
+       { .name = "sha224hmac", .mac = CRYPTO_SHA2_224_HMAC, .type = T_HMAC,
+         .evp_md = EVP_sha224 },
+       { .name = "sha256hmac", .mac = CRYPTO_SHA2_256_HMAC, .type = T_HMAC,
+         .evp_md = EVP_sha256 },
+       { .name = "sha384hmac", .mac = CRYPTO_SHA2_384_HMAC, .type = T_HMAC,
+         .evp_md = EVP_sha384 },
+       { .name = "sha512hmac", .mac = CRYPTO_SHA2_512_HMAC, .type = T_HMAC,
+         .evp_md = EVP_sha512 },
        { .name = "blake2b", .mac = CRYPTO_BLAKE2B, .type = T_HMAC,
          .evp_md = EVP_blake2b512 },
        { .name = "blake2s", .mac = CRYPTO_BLAKE2S, .type = T_HMAC,
@@ -352,6 +362,128 @@ generate_iv(size_t len, struct alg *alg)
 }
 
 static bool
+ocf_hash(struct alg *alg, const char *buffer, size_t size, char *digest,
+    int *cridp)
+{
+       struct session2_op sop;
+       struct crypt_op cop;
+       int fd;
+
+       memset(&sop, 0, sizeof(sop));
+       memset(&cop, 0, sizeof(cop));
+       sop.crid = crid;
+       sop.mac = alg->mac;
+       fd = crget();
+       if (ioctl(fd, CIOCGSESSION2, &sop) < 0) {
+               warn("cryptodev %s HASH not supported for device %s",
+                   alg->name, crfind(crid));
+               close(fd);
+               return (false);
+       }
+
+       cop.ses = sop.ses;
+       cop.op = 0;
+       cop.len = size;
+       cop.src = (char *)buffer;
+       cop.dst = NULL;
+       cop.mac = digest;
+       cop.iv = NULL;
+
+       if (ioctl(fd, CIOCCRYPT, &cop) < 0) {
+               warn("cryptodev %s (%zu) HASH failed for device %s", alg->name,
+                   size, crfind(crid));
+               close(fd);
+               return (false);
+       }
+
+       if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0)
+               warn("ioctl(CIOCFSESSION)");
+
+       close(fd);
+       *cridp = sop.crid;
+       return (true);
+}
+
+static void
+openssl_hash(struct alg *alg, const EVP_MD *md, const void *buffer,
+    size_t size, void *digest_out, unsigned *digest_sz_out)
+{
+       EVP_MD_CTX *mdctx;
+       const char *errs;
+       int rc;
+
+       errs = "";
+
+       mdctx = EVP_MD_CTX_create();
+       if (mdctx == NULL)
+               goto err_out;
+
+       rc = EVP_DigestInit_ex(mdctx, md, NULL);
+       if (rc != 1)
+               goto err_out;
+
+       rc = EVP_DigestUpdate(mdctx, buffer, size);
+       if (rc != 1)
+               goto err_out;
+
+       rc = EVP_DigestFinal_ex(mdctx, digest_out, digest_sz_out);
+       if (rc != 1)
+               goto err_out;
+
+       EVP_MD_CTX_destroy(mdctx);
+       return;
+
+err_out:
+       errx(1, "OpenSSL %s HASH failed%s: %s", alg->name, errs,
+           ERR_error_string(ERR_get_error(), NULL));
+}
+
+static void
+run_hash_test(struct alg *alg, size_t size)
+{
+       const EVP_MD *md;
+       char *buffer;
+       u_int digest_len;
+       int crid;
+       char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE];
+
+       memset(control_digest, 0x3c, sizeof(control_digest));
+       memset(test_digest, 0x3c, sizeof(test_digest));
+
+       md = alg->evp_md();
+       assert(EVP_MD_size(md) <= sizeof(control_digest));
+
+       buffer = alloc_buffer(size);
+
+       /* OpenSSL HASH. */
+       digest_len = sizeof(control_digest);
+       openssl_hash(alg, md, buffer, size, control_digest, &digest_len);
+
+       /* cryptodev HASH. */
+       if (!ocf_hash(alg, buffer, size, test_digest, &crid))
+               goto out;
+       if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) {
+               if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0)
+                       printf("%s (%zu) mismatch in trailer:\n",
+                           alg->name, size);
+               else
+                       printf("%s (%zu) mismatch:\n", alg->name, size);
+               printf("control:\n");
+               hexdump(control_digest, sizeof(control_digest), NULL, 0);
+               printf("test (cryptodev device %s):\n", crfind(crid));
+               hexdump(test_digest, sizeof(test_digest), NULL, 0);
+               goto out;
+       }
+
+       if (verbose)
+               printf("%s (%zu) matched (cryptodev device %s)\n",
+                   alg->name, size, crfind(crid));
+
+out:
+       free(buffer);
+}
+
+static bool
 ocf_hmac(struct alg *alg, const char *buffer, size_t size, const char *key,
     size_t key_len, char *digest, int *cridp)
 {
@@ -1031,6 +1163,9 @@ run_test(struct alg *alg, size_t size)
 {
 
        switch (alg->type) {
+       case T_HASH:
+               run_hash_test(alg, size);
+               break;
        case T_HMAC:
                run_hmac_test(alg, size);
                break;
@@ -1056,6 +1191,16 @@ run_test_sizes(struct alg *alg, size_t *sizes, u_int n
 }
 
 static void
+run_hash_tests(size_t *sizes, u_int nsizes)
+{
+       u_int i;
+
+       for (i = 0; i < nitems(algs); i++)
+               if (algs[i].type == T_HASH)
+                       run_test_sizes(&algs[i], sizes, nsizes);
+}
+
+static void
 run_hmac_tests(size_t *sizes, u_int nsizes)
 {
        u_int i;
@@ -1177,7 +1322,9 @@ main(int ac, char **av)
                }
        }
 
-       if (strcasecmp(algname, "hmac") == 0)
+       if (strcasecmp(algname, "hash") == 0)
+               run_hash_tests(sizes, nsizes);
+       else if (strcasecmp(algname, "hmac") == 0)
                run_hmac_tests(sizes, nsizes);
        else if (strcasecmp(algname, "blkcipher") == 0)
                run_blkcipher_tests(sizes, nsizes);
@@ -1186,6 +1333,7 @@ main(int ac, char **av)
        else if (strcasecmp(algname, "aead") == 0)
                run_aead_tests(sizes, nsizes);
        else if (strcasecmp(algname, "all") == 0) {
+               run_hash_tests(sizes, nsizes);
                run_hmac_tests(sizes, nsizes);
                run_blkcipher_tests(sizes, nsizes);
                run_authenc_tests(sizes, nsizes);
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to