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 .
This commit is contained in:
parent
21f8de74b4
commit
e2ca0f334d
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -421,6 +421,14 @@ swcr_authcompute(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
|
||||
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 cryptoini *cri)
|
||||
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 cryptoini *cri)
|
||||
(*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 hint)
|
||||
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);
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -61,6 +61,54 @@ static int SHA256Update_int(void *, const u_int8_t *, u_int16_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,
|
||||
|
@ -131,19 +131,29 @@ 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 },
|
||||
@ -351,6 +361,128 @@ generate_iv(size_t len, struct alg *alg)
|
||||
return (iv);
|
||||
}
|
||||
|
||||
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;
|
||||
@ -1055,6 +1190,16 @@ run_test_sizes(struct alg *alg, size_t *sizes, u_int nsizes)
|
||||
run_test(alg, sizes[i]);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user