Author: jhb
Date: Tue Jan  7 17:07:58 2020
New Revision: 356457
URL: https://svnweb.freebsd.org/changeset/base/356457

Log:
  Various cleanups to cryptocheck.
  
  - Rename 'blkcipher' to 'cipher'.  Some of the ciphers being tested
    are stream ciphers.
  - Rename 'authenc' to 'eta' as it is only testing ETA chained
    operations and not other combination modes.
  - Add a notion of an OCF session and some helper routines to try to
    reduce duplicated code.  This also uses a single session for both
    encrypt and decrypt operations during a single test.
  - Add tests to ensure that AEAD algorithms fail decryption with
    EBADMSG when given a corrupted tag.
  - Remove the transitional hack for COP_F_CIPHER_FIRST.
  - Update block comment to mention plain hashes.
  
  Reviewed by:  cem
  Sponsored by: Chelsio Communications
  Differential Revision:        https://reviews.freebsd.org/D22940

Modified:
  head/tools/tools/crypto/cryptocheck.c

Modified: head/tools/tools/crypto/cryptocheck.c
==============================================================================
--- head/tools/tools/crypto/cryptocheck.c       Tue Jan  7 17:02:49 2020        
(r356456)
+++ head/tools/tools/crypto/cryptocheck.c       Tue Jan  7 17:07:58 2020        
(r356457)
@@ -73,41 +73,50 @@
  *
  * Supported algorithms:
  *     all             Run all tests
- *     hmac            Run all hmac tests
- *     blkcipher       Run all block cipher tests
- *     authenc         Run all authenticated encryption tests
+ *     hash            Run all hash tests
+ *     mac             Run all mac tests
+ *     cipher          Run all cipher tests
+ *     eta             Run all encrypt-then-authenticate tests
  *     aead            Run all authenticated encryption with associated data
  *                     tests
  *
- * HMACs:
- *     sha1            sha1 hmac
- *     sha256          256-bit sha2 hmac
- *     sha384          384-bit sha2 hmac
- *     sha512          512-bit sha2 hmac
+ * Hashes:
+ *     sha1            SHA-1
+ *     sha224          224-bit SHA-2
+ *     sha256          256-bit SHA-2
+ *     sha384          384-bit SHA-2
+ *     sha512          512-bit SHA-2
  *     blake2b         Blake2-B
  *     blake2s         Blake2-S
  *
- * Block Ciphers:
- *     aes-cbc         128-bit aes cbc
- *     aes-cbc192      192-bit aes cbc
- *     aes-cbc256      256-bit aes cbc
- *     aes-ctr         128-bit aes ctr
- *     aes-ctr192      192-bit aes ctr
- *     aes-ctr256      256-bit aes ctr
- *     aes-xts         128-bit aes xts
- *     aes-xts256      256-bit aes xts
+ * MACs:
+ *     sha1hmac        SHA-1 HMAC
+ *     sha224hmac      224-bit SHA-2 HMAC
+ *     sha256hmac      256-bit SHA-2 HMAC
+ *     sha384hmac      384-bit SHA-2 HMAC
+ *     sha512hmac      512-bit SHA-2 HMAC
+ *
+ * Ciphers:
+ *     aes-cbc         128-bit AES-CBC
+ *     aes-cbc192      192-bit AES-CBC
+ *     aes-cbc256      256-bit AES-CBC
+ *     aes-ctr         128-bit AES-CTR
+ *     aes-ctr192      192-bit AES-CTR
+ *     aes-ctr256      256-bit AES-CTR
+ *     aes-xts         128-bit AES-XTS
+ *     aes-xts256      256-bit AES-XTS
  *     chacha20
  *
- * Authenticated Encryption:
- *     <block cipher>+<hmac>
+ * Encrypt then Authenticate:
+ *     <cipher>+<mac>
  *
  * Authenticated Encryption with Associated Data:
- *     aes-gcm         128-bit aes gcm
- *     aes-gcm192      192-bit aes gcm
- *     aes-gcm256      256-bit aes gcm
- *     aes-ccm         128-bit aes ccm
- *     aes-ccm192      192-bit aes ccm
- *     aes-ccm256      256-bit aes ccm
+ *     aes-gcm         128-bit AES-GCM
+ *     aes-gcm192      192-bit AES-GCM
+ *     aes-gcm256      256-bit AES-GCM
+ *     aes-ccm         128-bit AES-CCM
+ *     aes-ccm192      192-bit AES-CCM
+ *     aes-ccm256      256-bit AES-CCM
  */
 
 #include <sys/param.h>
@@ -126,16 +135,17 @@
 
 #include <crypto/cryptodev.h>
 
-/* XXX: Temporary hack */
-#ifndef COP_F_CIPHER_FIRST
-#define        COP_F_CIPHER_FIRST      0x0001  /* Cipher before MAC. */
-#endif
+struct ocf_session {
+       int fd;
+       int ses;
+       int crid;
+};
 
-struct alg {
+const struct alg {
        const char *name;
        int cipher;
        int mac;
-       enum { T_HASH, T_HMAC, T_BLKCIPHER, T_AUTHENC, T_GCM, T_CCM } type;
+       enum { T_HASH, T_HMAC, T_CIPHER, T_ETA, T_AEAD } type;
        const EVP_CIPHER *(*evp_cipher)(void);
        const EVP_MD *(*evp_md)(void);
 } algs[] = {
@@ -163,41 +173,41 @@ struct alg {
          .evp_md = EVP_blake2b512 },
        { .name = "blake2s", .mac = CRYPTO_BLAKE2S, .type = T_HASH,
          .evp_md = EVP_blake2s256 },
-       { .name = "aes-cbc", .cipher = CRYPTO_AES_CBC, .type = T_BLKCIPHER,
+       { .name = "aes-cbc", .cipher = CRYPTO_AES_CBC, .type = T_CIPHER,
          .evp_cipher = EVP_aes_128_cbc },
-       { .name = "aes-cbc192", .cipher = CRYPTO_AES_CBC, .type = T_BLKCIPHER,
+       { .name = "aes-cbc192", .cipher = CRYPTO_AES_CBC, .type = T_CIPHER,
          .evp_cipher = EVP_aes_192_cbc },
-       { .name = "aes-cbc256", .cipher = CRYPTO_AES_CBC, .type = T_BLKCIPHER,
+       { .name = "aes-cbc256", .cipher = CRYPTO_AES_CBC, .type = T_CIPHER,
          .evp_cipher = EVP_aes_256_cbc },
-       { .name = "aes-ctr", .cipher = CRYPTO_AES_ICM, .type = T_BLKCIPHER,
+       { .name = "aes-ctr", .cipher = CRYPTO_AES_ICM, .type = T_CIPHER,
          .evp_cipher = EVP_aes_128_ctr },
-       { .name = "aes-ctr192", .cipher = CRYPTO_AES_ICM, .type = T_BLKCIPHER,
+       { .name = "aes-ctr192", .cipher = CRYPTO_AES_ICM, .type = T_CIPHER,
          .evp_cipher = EVP_aes_192_ctr },
-       { .name = "aes-ctr256", .cipher = CRYPTO_AES_ICM, .type = T_BLKCIPHER,
+       { .name = "aes-ctr256", .cipher = CRYPTO_AES_ICM, .type = T_CIPHER,
          .evp_cipher = EVP_aes_256_ctr },
-       { .name = "aes-xts", .cipher = CRYPTO_AES_XTS, .type = T_BLKCIPHER,
+       { .name = "aes-xts", .cipher = CRYPTO_AES_XTS, .type = T_CIPHER,
          .evp_cipher = EVP_aes_128_xts },
-       { .name = "aes-xts256", .cipher = CRYPTO_AES_XTS, .type = T_BLKCIPHER,
+       { .name = "aes-xts256", .cipher = CRYPTO_AES_XTS, .type = T_CIPHER,
          .evp_cipher = EVP_aes_256_xts },
-       { .name = "chacha20", .cipher = CRYPTO_CHACHA20, .type = T_BLKCIPHER,
+       { .name = "chacha20", .cipher = CRYPTO_CHACHA20, .type = T_CIPHER,
          .evp_cipher = EVP_chacha20 },
        { .name = "aes-gcm", .cipher = CRYPTO_AES_NIST_GCM_16,
-         .mac = CRYPTO_AES_128_NIST_GMAC, .type = T_GCM,
+         .mac = CRYPTO_AES_128_NIST_GMAC, .type = T_AEAD,
          .evp_cipher = EVP_aes_128_gcm },
        { .name = "aes-gcm192", .cipher = CRYPTO_AES_NIST_GCM_16,
-         .mac = CRYPTO_AES_192_NIST_GMAC, .type = T_GCM,
+         .mac = CRYPTO_AES_192_NIST_GMAC, .type = T_AEAD,
          .evp_cipher = EVP_aes_192_gcm },
        { .name = "aes-gcm256", .cipher = CRYPTO_AES_NIST_GCM_16,
-         .mac = CRYPTO_AES_256_NIST_GMAC, .type = T_GCM,
+         .mac = CRYPTO_AES_256_NIST_GMAC, .type = T_AEAD,
          .evp_cipher = EVP_aes_256_gcm },
        { .name = "aes-ccm", .cipher = CRYPTO_AES_CCM_16,
-         .mac = CRYPTO_AES_CCM_CBC_MAC, .type = T_CCM,
+         .mac = CRYPTO_AES_CCM_CBC_MAC, .type = T_AEAD,
          .evp_cipher = EVP_aes_128_ccm },
        { .name = "aes-ccm192", .cipher = CRYPTO_AES_CCM_16,
-         .mac = CRYPTO_AES_CCM_CBC_MAC, .type = T_CCM,
+         .mac = CRYPTO_AES_CCM_CBC_MAC, .type = T_AEAD,
          .evp_cipher = EVP_aes_192_ccm },
        { .name = "aes-ccm256", .cipher = CRYPTO_AES_CCM_16,
-         .mac = CRYPTO_AES_CCM_CBC_MAC, .type = T_CCM,
+         .mac = CRYPTO_AES_CCM_CBC_MAC, .type = T_AEAD,
          .evp_cipher = EVP_aes_256_ccm },
 };
 
@@ -213,7 +223,7 @@ usage(void)
        exit(1);
 }
 
-static struct alg *
+static const struct alg *
 find_alg(const char *name)
 {
        u_int i;
@@ -225,42 +235,49 @@ find_alg(const char *name)
 }
 
 static struct alg *
-build_authenc(struct alg *cipher, struct alg *hmac)
+build_eta(const struct alg *cipher, const struct alg *mac)
 {
-       static struct alg authenc;
+       struct alg *eta;
        char *name;
 
-       assert(cipher->type == T_BLKCIPHER);
-       assert(hmac->type == T_HMAC);
-       memset(&authenc, 0, sizeof(authenc));
-       asprintf(&name, "%s+%s", cipher->name, hmac->name);
-       authenc.name = name;
-       authenc.cipher = cipher->cipher;
-       authenc.mac = hmac->mac;
-       authenc.type = T_AUTHENC;
-       authenc.evp_cipher = cipher->evp_cipher;
-       authenc.evp_md = hmac->evp_md;
-       return (&authenc);
+       assert(cipher->type == T_CIPHER);
+       assert(mac->type == T_HMAC);
+       eta = calloc(1, sizeof(*eta));
+       asprintf(&name, "%s+%s", cipher->name, mac->name);
+       eta->name = name;
+       eta->cipher = cipher->cipher;
+       eta->mac = mac->mac;
+       eta->type = T_ETA;
+       eta->evp_cipher = cipher->evp_cipher;
+       eta->evp_md = mac->evp_md;
+       return (eta);
 }
 
+static void
+free_eta(struct alg *eta)
+{
+       free(__DECONST(char *, eta->name));
+       free(eta);
+}
+
 static struct alg *
-build_authenc_name(const char *name)
+build_eta_name(const char *name)
 {
-       struct alg *cipher, *hmac;
-       const char *hmac_name;
+       const struct alg *cipher, *mac;
+       const char *mac_name;
        char *cp, *cipher_name;
 
        cp = strchr(name, '+');
        cipher_name = strndup(name, cp - name);
-       hmac_name = cp + 1;
+       mac_name = cp + 1;
        cipher = find_alg(cipher_name);
        free(cipher_name);
-       if (cipher == NULL)
+       if (cipher == NULL || cipher->type != T_CIPHER)
                errx(1, "Invalid cipher %s", cipher_name);
-       hmac = find_alg(hmac_name);
-       if (hmac == NULL)
-               errx(1, "Invalid hash %s", hmac_name);
-       return (build_authenc(cipher, hmac));
+       mac = find_alg(mac_name);
+       if (mac == NULL || mac->type != T_HMAC)
+               errx(1, "Invalid hmac %s", mac_name);
+       return (build_eta(cipher, mac));
 }
 
 static int
@@ -371,7 +388,7 @@ alloc_buffer(size_t len)
 }
 
 static char *
-generate_iv(size_t len, struct alg *alg)
+generate_iv(size_t len, const struct alg *alg)
 {
        char *iv;
 
@@ -402,51 +419,93 @@ generate_iv(size_t len, struct alg *alg)
        return (iv);
 }
 
+static void
+ocf_init_sop(struct session2_op *sop)
+{
+       memset(sop, 0, sizeof(*sop));
+       sop->crid = crid;
+}
+
 static bool
-ocf_hash(struct alg *alg, const char *buffer, size_t size, char *digest,
-    int *cridp)
+ocf_init_session(struct session2_op *sop, const char *type, const char *name,
+    struct ocf_session *ses)
 {
-       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));
+       if (ioctl(fd, CIOCGSESSION2, sop) < 0) {
+               warn("cryptodev %s %s not supported for device %s",
+                   type, name, crfind(crid));
                close(fd);
+               ses->fd = -1;
                return (false);
        }
+       ses->fd = fd;
+       ses->ses = sop->ses;
+       ses->crid = sop->crid;
+       return (true);
+}
 
-       cop.ses = sop.ses;
+static void
+ocf_destroy_session(struct ocf_session *ses)
+{
+       if (ses->fd == -1)
+               return;
+
+       if (ioctl(ses->fd, CIOCFSESSION, &ses->ses) < 0)
+               warn("ioctl(CIOCFSESSION)");
+
+       close(ses->fd);
+}
+
+static void
+ocf_init_cop(const struct ocf_session *ses, struct crypt_op *cop)
+{
+       memset(cop, 0, sizeof(*cop));
+       cop->ses = ses->ses;
+}
+
+static void
+ocf_init_caead(const struct ocf_session *ses, struct crypt_aead *caead)
+{
+       memset(caead, 0, sizeof(*caead));
+       caead->ses = ses->ses;
+}
+
+static bool
+ocf_hash(const struct alg *alg, const char *buffer, size_t size, char *digest,
+    int *cridp)
+{
+       struct ocf_session ses;
+       struct session2_op sop;
+       struct crypt_op cop;
+       int error;
+
+       ocf_init_sop(&sop);
+       sop.mac = alg->mac;
+       if (!ocf_init_session(&sop, "HASH", alg->name, &ses))
+               return (false);
+
+       ocf_init_cop(&ses, &cop);
        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) {
+       if (ioctl(ses.fd, CIOCCRYPT, &cop) < 0) {
                warn("cryptodev %s (%zu) HASH failed for device %s", alg->name,
                    size, crfind(crid));
-               close(fd);
+               ocf_destroy_session(&ses);
                return (false);
        }
 
-       if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0)
-               warn("ioctl(CIOCFSESSION)");
-
-       close(fd);
-       *cridp = sop.crid;
+       *cridp = ses.crid;
+       ocf_destroy_session(&ses);
        return (true);
 }
 
 static void
-openssl_hash(struct alg *alg, const EVP_MD *md, const void *buffer,
+openssl_hash(const struct alg *alg, const EVP_MD *md, const void *buffer,
     size_t size, void *digest_out, unsigned *digest_sz_out)
 {
        EVP_MD_CTX *mdctx;
@@ -480,7 +539,7 @@ err_out:
 }
 
 static void
-run_hash_test(struct alg *alg, size_t size)
+run_hash_test(const struct alg *alg, size_t size)
 {
        const EVP_MD *md;
        char *buffer;
@@ -525,52 +584,40 @@ out:
 }
 
 static bool
-ocf_hmac(struct alg *alg, const char *buffer, size_t size, const char *key,
-    size_t key_len, char *digest, int *cridp)
+ocf_hmac(const struct alg *alg, const char *buffer, size_t size,
+    const char *key, size_t key_len, char *digest, int *cridp)
 {
+       struct ocf_session ses;
        struct session2_op sop;
        struct crypt_op cop;
-       int fd;
 
-       memset(&sop, 0, sizeof(sop));
-       memset(&cop, 0, sizeof(cop));
-       sop.crid = crid;
+       ocf_init_sop(&sop);
        sop.mackeylen = key_len;
        sop.mackey = (char *)key;
        sop.mac = alg->mac;
-       fd = crget();
-       if (ioctl(fd, CIOCGSESSION2, &sop) < 0) {
-               warn("cryptodev %s HMAC not supported for device %s",
-                   alg->name, crfind(crid));
-               close(fd);
+       if (!ocf_init_session(&sop, "HMAC", alg->name, &ses))
                return (false);
-       }
 
-       cop.ses = sop.ses;
+       ocf_init_cop(&ses, &cop);
        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) {
+       if (ioctl(ses.fd, CIOCCRYPT, &cop) < 0) {
                warn("cryptodev %s (%zu) HMAC failed for device %s", alg->name,
                    size, crfind(crid));
-               close(fd);
+               ocf_destroy_session(&ses);
                return (false);
        }
 
-       if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0)
-               warn("ioctl(CIOCFSESSION)");
-
-       close(fd);
-       *cridp = sop.crid;
+       *cridp = ses.crid;
+       ocf_destroy_session(&ses);
        return (true);
 }
 
 static void
-run_hmac_test(struct alg *alg, size_t size)
+run_hmac_test(const struct alg *alg, size_t size)
 {
        const EVP_MD *md;
        char *key, *buffer;
@@ -621,7 +668,7 @@ out:
 }
 
 static void
-openssl_cipher(struct alg *alg, const EVP_CIPHER *cipher, const char *key,
+openssl_cipher(const struct alg *alg, const EVP_CIPHER *cipher, const char 
*key,
     const char *iv, const char *input, char *output, size_t size, int enc)
 {
        EVP_CIPHER_CTX *ctx;
@@ -652,59 +699,48 @@ openssl_cipher(struct alg *alg, const EVP_CIPHER *ciph
 }
 
 static bool
-ocf_cipher(struct alg *alg, const char *key, size_t key_len,
-    const char *iv, const char *input, char *output, size_t size, int enc,
-    int *cridp)
+ocf_init_cipher_session(const struct alg *alg, const char *key, size_t key_len,
+    struct ocf_session *ses)
 {
        struct session2_op sop;
-       struct crypt_op cop;
-       int fd;
 
-       memset(&sop, 0, sizeof(sop));
-       memset(&cop, 0, sizeof(cop));
-       sop.crid = crid;
+       ocf_init_sop(&sop);
        sop.keylen = key_len;
        sop.key = (char *)key;
        sop.cipher = alg->cipher;
-       fd = crget();
-       if (ioctl(fd, CIOCGSESSION2, &sop) < 0) {
-               warn("cryptodev %s block cipher not supported for device %s",
-                   alg->name, crfind(crid));
-               close(fd);
-               return (false);
-       }
+       return (ocf_init_session(&sop, "cipher", alg->name, ses));
+}
 
-       cop.ses = sop.ses;
-       cop.op = enc ? COP_ENCRYPT : COP_DECRYPT;
+static bool
+ocf_cipher(const struct ocf_session *ses, const struct alg *alg, const char 
*iv,
+    const char *input, char *output, size_t size, int op)
+{
+       struct crypt_op cop;
+
+       ocf_init_cop(ses, &cop);
+       cop.op = op;
        cop.len = size;
        cop.src = (char *)input;
        cop.dst = output;
-       cop.mac = NULL;
        cop.iv = (char *)iv;
 
-       if (ioctl(fd, CIOCCRYPT, &cop) < 0) {
-               warn("cryptodev %s (%zu) block cipher failed for device %s",
+       if (ioctl(ses->fd, CIOCCRYPT, &cop) < 0) {
+               warn("cryptodev %s (%zu) cipher 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
-run_blkcipher_test(struct alg *alg, size_t size)
+run_cipher_test(const struct alg *alg, size_t size)
 {
+       struct ocf_session ses;
        const EVP_CIPHER *cipher;
        char *buffer, *cleartext, *ciphertext;
        char *iv, *key;
        u_int iv_len, key_len;
-       int crid;
 
        cipher = alg->evp_cipher();
        if (size % EVP_CIPHER_block_size(cipher) != 0) {
@@ -739,37 +775,39 @@ run_blkcipher_test(struct alg *alg, size_t size)
                exit(1);
        }
 
+       if (!ocf_init_cipher_session(alg, key, key_len, &ses))
+               goto out;
+
        /* OCF encrypt. */
-       if (!ocf_cipher(alg, key, key_len, iv, cleartext, buffer, size, 1,
-           &crid))
+       if (!ocf_cipher(&ses, alg, iv, cleartext, buffer, size, COP_ENCRYPT))
                goto out;
        if (memcmp(ciphertext, buffer, size) != 0) {
                printf("%s (%zu) encryption mismatch:\n", alg->name, size);
                printf("control:\n");
                hexdump(ciphertext, size, NULL, 0);
-               printf("test (cryptodev device %s):\n", crfind(crid));
+               printf("test (cryptodev device %s):\n", crfind(ses.crid));
                hexdump(buffer, size, NULL, 0);
                goto out;
        }
 
        /* OCF decrypt. */
-       if (!ocf_cipher(alg, key, key_len, iv, ciphertext, buffer, size, 0,
-           &crid))
+       if (!ocf_cipher(&ses, alg, iv, ciphertext, buffer, size, COP_DECRYPT))
                goto out;
        if (memcmp(cleartext, buffer, size) != 0) {
                printf("%s (%zu) decryption mismatch:\n", alg->name, size);
                printf("control:\n");
                hexdump(cleartext, size, NULL, 0);
-               printf("test (cryptodev device %s):\n", crfind(crid));
+               printf("test (cryptodev device %s):\n", crfind(ses.crid));
                hexdump(buffer, size, NULL, 0);
                goto out;
        }
 
        if (verbose)
                printf("%s (%zu) matched (cryptodev device %s)\n",
-                   alg->name, size, crfind(crid));
+                   alg->name, size, crfind(ses.crid));
 
 out:
+       ocf_destroy_session(&ses);
        free(ciphertext);
        free(buffer);
        free(cleartext);
@@ -778,37 +816,35 @@ out:
 }
 
 static bool
-ocf_authenc(struct alg *alg, const char *cipher_key, size_t cipher_key_len,
-    const char *iv, size_t iv_len, const char *auth_key, size_t auth_key_len,
-    const char *aad, size_t aad_len, const char *input, char *output,
-    size_t size, char *digest, int enc, int *cridp)
+ocf_init_eta_session(const struct alg *alg, const char *cipher_key,
+    size_t cipher_key_len, const char *auth_key, size_t auth_key_len,
+    struct ocf_session *ses)
 {
        struct session2_op sop;
-       int fd;
 
-       memset(&sop, 0, sizeof(sop));
-       sop.crid = crid;
+       ocf_init_sop(&sop);
        sop.keylen = cipher_key_len;
        sop.key = (char *)cipher_key;
        sop.cipher = alg->cipher;
        sop.mackeylen = auth_key_len;
        sop.mackey = (char *)auth_key;
        sop.mac = alg->mac;
-       fd = crget();
-       if (ioctl(fd, CIOCGSESSION2, &sop) < 0) {
-               warn("cryptodev %s AUTHENC not supported for device %s",
-                   alg->name, crfind(crid));
-               close(fd);
-               return (false);
-       }
+       return (ocf_init_session(&sop, "ETA", alg->name, ses));
+}
 
+static bool
+ocf_eta(const struct ocf_session *ses, const struct alg *alg, const char *iv,
+    size_t iv_len, const char *aad, size_t aad_len, const char *input,
+    char *output, size_t size, char *digest, int op)
+{
+       int ret;
+
        if (aad_len != 0) {
                struct crypt_aead caead;
 
-               memset(&caead, 0, sizeof(caead));
-               caead.ses = sop.ses;
-               caead.op = enc ? COP_ENCRYPT : COP_DECRYPT;
-               caead.flags = enc ? COP_F_CIPHER_FIRST : 0;
+               ocf_init_caead(ses, &caead);
+               caead.op = op;
+               caead.flags = op == COP_ENCRYPT ? COP_F_CIPHER_FIRST : 0;
                caead.len = size;
                caead.aadlen = aad_len;
                caead.ivlen = iv_len;
@@ -818,50 +854,40 @@ ocf_authenc(struct alg *alg, const char *cipher_key, s
                caead.tag = digest;
                caead.iv = (char *)iv;
 
-               if (ioctl(fd, CIOCCRYPTAEAD, &caead) < 0) {
-                       warn("cryptodev %s (%zu) failed for device %s",
-                           alg->name, size, crfind(crid));
-                       close(fd);
-                       return (false);
-               }
+               ret = ioctl(ses->fd, CIOCCRYPTAEAD, &caead);
        } else {
                struct crypt_op cop;
 
-               memset(&cop, 0, sizeof(cop));
-               cop.ses = sop.ses;
-               cop.op = enc ? COP_ENCRYPT : COP_DECRYPT;
-               cop.flags = enc ? COP_F_CIPHER_FIRST : 0;
+               ocf_init_cop(ses, &cop);
+               cop.op = op;
+               cop.flags = op == COP_ENCRYPT ? COP_F_CIPHER_FIRST : 0;
                cop.len = size;
                cop.src = (char *)input;
                cop.dst = output;
                cop.mac = digest;
                cop.iv = (char *)iv;
 
-               if (ioctl(fd, CIOCCRYPT, &cop) < 0) {
-                       warn("cryptodev %s (%zu) AUTHENC failed for device %s",
-                           alg->name, size, crfind(crid));
-                       close(fd);
-                       return (false);
-               }
+               ret = ioctl(ses->fd, CIOCCRYPT, &cop);
        }
 
-       if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0)
-               warn("ioctl(CIOCFSESSION)");
+       if (ret < 0) {
+               warn("cryptodev %s (%zu) ETA failed for device %s",
+                   alg->name, size, crfind(crid));
+               return (false);
+       }
 
-       close(fd);
-       *cridp = sop.crid;
        return (true);
 }
 
 static void
-run_authenc_test(struct alg *alg, size_t size)
+run_eta_test(const struct alg *alg, size_t size)
 {
+       struct ocf_session ses;
        const EVP_CIPHER *cipher;
        const EVP_MD *md;
        char *aad, *buffer, *cleartext, *ciphertext;
        char *iv, *auth_key, *cipher_key;
-       u_int iv_len, auth_key_len, cipher_key_len, digest_len;
-       int crid;
+       u_int i, iv_len, auth_key_len, cipher_key_len, digest_len;
        char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE];
 
        cipher = alg->evp_cipher();
@@ -904,16 +930,20 @@ run_authenc_test(struct alg *alg, size_t size)
                errx(1, "OpenSSL %s (%zu) HMAC failed: %s", alg->name,
                    size, ERR_error_string(ERR_get_error(), NULL));
 
+       if (!ocf_init_eta_session(alg, cipher_key, cipher_key_len, auth_key,
+           auth_key_len, &ses))
+               goto out;
+
        /* OCF encrypt + HMAC. */
-       if (!ocf_authenc(alg, cipher_key, cipher_key_len, iv, iv_len, auth_key,
-           auth_key_len, aad_len != 0 ? cleartext : NULL, aad_len,
-           cleartext + aad_len, buffer + aad_len, size, test_digest, 1, &crid))
+       if (!ocf_eta(&ses, alg, iv, iv_len,
+           aad_len != 0 ? cleartext : NULL, aad_len, cleartext + aad_len,
+           buffer + aad_len, size, test_digest, COP_ENCRYPT))
                goto out;
        if (memcmp(ciphertext + aad_len, buffer + aad_len, size) != 0) {
                printf("%s (%zu) encryption mismatch:\n", alg->name, size);
                printf("control:\n");
                hexdump(ciphertext + aad_len, size, NULL, 0);
-               printf("test (cryptodev device %s):\n", crfind(crid));
+               printf("test (cryptodev device %s):\n", crfind(ses.crid));
                hexdump(buffer + aad_len, size, NULL, 0);
                goto out;
        }
@@ -926,45 +956,31 @@ run_authenc_test(struct alg *alg, size_t size)
                            size);
                printf("control:\n");
                hexdump(control_digest, sizeof(control_digest), NULL, 0);
-               printf("test (cryptodev device %s):\n", crfind(crid));
+               printf("test (cryptodev device %s):\n", crfind(ses.crid));
                hexdump(test_digest, sizeof(test_digest), NULL, 0);
                goto out;
        }
 
        /* OCF HMAC + decrypt. */
-       memset(test_digest, 0x3c, sizeof(test_digest));
-       if (!ocf_authenc(alg, cipher_key, cipher_key_len, iv, iv_len, auth_key,
-           auth_key_len, aad_len != 0 ? ciphertext : NULL, aad_len,
-           ciphertext + aad_len, buffer + aad_len, size, test_digest, 0,
-           &crid))
+       if (!ocf_eta(&ses, alg, iv, iv_len,
+           aad_len != 0 ? ciphertext : NULL, aad_len, ciphertext + aad_len,
+           buffer + aad_len, size, test_digest, COP_DECRYPT))
                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) dec hash mismatch in trailer:\n",
-                           alg->name, size);
-               else
-                       printf("%s (%zu) dec hash 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 (memcmp(cleartext + aad_len, buffer + aad_len, size) != 0) {
                printf("%s (%zu) decryption mismatch:\n", alg->name, size);
                printf("control:\n");
                hexdump(cleartext, size, NULL, 0);
-               printf("test (cryptodev device %s):\n", crfind(crid));
+               printf("test (cryptodev device %s):\n", crfind(ses.crid));
                hexdump(buffer, size, NULL, 0);
                goto out;
        }
 
        if (verbose)
                printf("%s (%zu) matched (cryptodev device %s)\n",
-                   alg->name, size, crfind(crid));
+                   alg->name, size, crfind(ses.crid));
 
 out:
+       ocf_destroy_session(&ses);
        free(ciphertext);
        free(buffer);
        free(cleartext);
@@ -974,9 +990,9 @@ out:
 }
 
 static void
-openssl_gcm_encrypt(struct alg *alg, const EVP_CIPHER *cipher, const char *key,
-    const char *iv, const char *aad, size_t aad_len, const char *input,
-    char *output, size_t size, char *tag)
+openssl_gcm_encrypt(const struct alg *alg, const EVP_CIPHER *cipher,
+    const char *key, const char *iv, const char *aad, size_t aad_len,
+    const char *input, char *output, size_t size, char *tag)
 {
        EVP_CIPHER_CTX *ctx;
        int outl, total;
@@ -1016,63 +1032,11 @@ openssl_gcm_encrypt(struct alg *alg, const EVP_CIPHER 
        EVP_CIPHER_CTX_free(ctx);
 }
 
-static bool
-ocf_gcm(struct alg *alg, const char *key, size_t key_len, const char *iv,
-    size_t iv_len, const char *aad, size_t aad_len, const char *input,
-    char *output, size_t size, char *tag, int enc, int *cridp)
-{
-       struct session2_op sop;
-       struct crypt_aead caead;
-       int fd;
-
-       memset(&sop, 0, sizeof(sop));
-       memset(&caead, 0, sizeof(caead));
-       sop.crid = crid;
-       sop.keylen = key_len;
-       sop.key = (char *)key;
-       sop.cipher = alg->cipher;
-       sop.mackeylen = key_len;
-       sop.mackey = (char *)key;
-       sop.mac = alg->mac;
-       fd = crget();
-       if (ioctl(fd, CIOCGSESSION2, &sop) < 0) {
-               warn("cryptodev %s not supported for device %s",
-                   alg->name, crfind(crid));
-               close(fd);
-               return (false);
-       }
-
-       caead.ses = sop.ses;
-       caead.op = enc ? COP_ENCRYPT : COP_DECRYPT;
-       caead.len = size;
-       caead.aadlen = aad_len;
-       caead.ivlen = iv_len;
-       caead.src = (char *)input;
-       caead.dst = output;
-       caead.aad = (char *)aad;
-       caead.tag = tag;
-       caead.iv = (char *)iv;
-
-       if (ioctl(fd, CIOCCRYPTAEAD, &caead) < 0) {
-               warn("cryptodev %s (%zu) 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);
-}
-
 #ifdef notused
 static bool
-openssl_gcm_decrypt(struct alg *alg, const EVP_CIPHER *cipher, const char *key,
-    const char *iv, const char *aad, size_t aad_len, const char *input,
-    char *output, size_t size, char *tag)
+openssl_gcm_decrypt(const struct alg *alg, const EVP_CIPHER *cipher,
+    const char *key, const char *iv, const char *aad, size_t aad_len,
+    const char *input, char *output, size_t size, char *tag)
 {
        EVP_CIPHER_CTX *ctx;
        int outl, total;
@@ -1114,96 +1078,10 @@ openssl_gcm_decrypt(struct alg *alg, const EVP_CIPHER 
 #endif
 
 static void
-run_gcm_test(struct alg *alg, size_t size)
+openssl_ccm_encrypt(const struct alg *alg, const EVP_CIPHER *cipher,
+    const char *key, const char *iv, size_t iv_len, const char *aad,
+    size_t aad_len, const char *input, char *output, size_t size, char *tag)
 {
-       const EVP_CIPHER *cipher;
-       char *aad, *buffer, *cleartext, *ciphertext;
-       char *iv, *key;
-       u_int iv_len, key_len;
-       int crid;
-       char control_tag[AES_GMAC_HASH_LEN], test_tag[AES_GMAC_HASH_LEN];
-
-       cipher = alg->evp_cipher();
-       if (size % EVP_CIPHER_block_size(cipher) != 0) {
-               if (verbose)
-                       printf(
-                           "%s (%zu): invalid buffer size (block size %d)\n",
-                           alg->name, size, EVP_CIPHER_block_size(cipher));
-               return;
-       }
-
-       memset(control_tag, 0x3c, sizeof(control_tag));
-       memset(test_tag, 0x3c, sizeof(test_tag));
-
-       key_len = EVP_CIPHER_key_length(cipher);
-       iv_len = EVP_CIPHER_iv_length(cipher);
-
-       key = alloc_buffer(key_len);
-       iv = generate_iv(iv_len, alg);
-       cleartext = alloc_buffer(size);
-       buffer = malloc(size);
-       ciphertext = malloc(size);
-       if (aad_len != 0)
-               aad = alloc_buffer(aad_len);
-       else
-               aad = NULL;
-
-       /* OpenSSL encrypt */
-       openssl_gcm_encrypt(alg, cipher, key, iv, aad, aad_len, cleartext,
-           ciphertext, size, control_tag);
-
-       /* OCF encrypt */
-       if (!ocf_gcm(alg, key, key_len, iv, iv_len, aad, aad_len, cleartext,
-           buffer, size, test_tag, 1, &crid))
-               goto out;
-       if (memcmp(ciphertext, buffer, size) != 0) {
-               printf("%s (%zu) encryption mismatch:\n", alg->name, size);
-               printf("control:\n");
-               hexdump(ciphertext, size, NULL, 0);
-               printf("test (cryptodev device %s):\n", crfind(crid));
-               hexdump(buffer, size, NULL, 0);
-               goto out;
-       }
-       if (memcmp(control_tag, test_tag, sizeof(control_tag)) != 0) {
-               printf("%s (%zu) enc tag mismatch:\n", alg->name, size);
-               printf("control:\n");
-               hexdump(control_tag, sizeof(control_tag), NULL, 0);
-               printf("test (cryptodev device %s):\n", crfind(crid));
-               hexdump(test_tag, sizeof(test_tag), NULL, 0);
-               goto out;
-       }
-
-       /* OCF decrypt */
-       if (!ocf_gcm(alg, key, key_len, iv, iv_len, aad, aad_len, ciphertext,
-           buffer, size, control_tag, 0, &crid))
-               goto out;
-       if (memcmp(cleartext, buffer, size) != 0) {
-               printf("%s (%zu) decryption mismatch:\n", alg->name, size);
-               printf("control:\n");
-               hexdump(cleartext, size, NULL, 0);
-               printf("test (cryptodev device %s):\n", crfind(crid));
-               hexdump(buffer, size, NULL, 0);
-               goto out;
-       }
-
-       if (verbose)
-               printf("%s (%zu) matched (cryptodev device %s)\n",
-                   alg->name, size, crfind(crid));
-
-out:
-       free(aad);
-       free(ciphertext);
-       free(buffer);
-       free(cleartext);
-       free(iv);
-       free(key);
-}
-
-static void
-openssl_ccm_encrypt(struct alg *alg, const EVP_CIPHER *cipher, const char *key,
-    const char *iv, size_t iv_len, const char *aad, size_t aad_len,
-                   const char *input, char *output, size_t size, char *tag)
-{
        EVP_CIPHER_CTX *ctx;
        int outl, total;
 
@@ -1255,34 +1133,30 @@ openssl_ccm_encrypt(struct alg *alg, const EVP_CIPHER 
 }
 
 static bool
-ocf_ccm(struct alg *alg, const char *key, size_t key_len, const char *iv,
-    size_t iv_len, const char *aad, size_t aad_len, const char *input,
-    char *output, size_t size, char *tag, int enc, int *cridp)
+ocf_init_aead_session(const struct alg *alg, const char *key, size_t key_len,
+    struct ocf_session *ses)
 {
        struct session2_op sop;
-       struct crypt_aead caead;
-       int fd;
-       bool rv;
 
-       memset(&sop, 0, sizeof(sop));
-       memset(&caead, 0, sizeof(caead));
-       sop.crid = crid;
+       ocf_init_sop(&sop);
        sop.keylen = key_len;
        sop.key = (char *)key;
        sop.cipher = alg->cipher;
        sop.mackeylen = key_len;
        sop.mackey = (char *)key;
        sop.mac = alg->mac;
-       fd = crget();
-       if (ioctl(fd, CIOCGSESSION2, &sop) < 0) {
-               warn("cryptodev %s not supported for device %s",
-                   alg->name, crfind(crid));
-               close(fd);
-               return (false);
-       }
+       return (ocf_init_session(&sop, "AEAD", alg->name, ses));
+}
 
-       caead.ses = sop.ses;
-       caead.op = enc ? COP_ENCRYPT : COP_DECRYPT;
+static int
+ocf_aead(const struct ocf_session *ses, const struct alg *alg, const char *iv,
+    size_t iv_len, const char *aad, size_t aad_len, const char *input,
+    char *output, size_t size, char *tag, int op)
+{
+       struct crypt_aead caead;
+
+       ocf_init_caead(ses, &caead);
+       caead.op = op;
        caead.len = size;
        caead.aadlen = aad_len;
        caead.ivlen = iv_len;
@@ -1292,30 +1166,23 @@ ocf_ccm(struct alg *alg, const char *key, size_t key_l
        caead.tag = tag;
        caead.iv = (char *)iv;
 

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to