svn commit: r356457 - head/tools/tools/crypto

John Baldwin jhb at FreeBSD.org
Tue Jan 7 17:07:59 UTC 2020


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 ***


More information about the svn-src-head mailing list