diff --git a/sys/opencrypto/cryptodev.c b/sys/opencrypto/cryptodev.c index e80de0c159a4..605cc0818636 100644 --- a/sys/opencrypto/cryptodev.c +++ b/sys/opencrypto/cryptodev.c @@ -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; diff --git a/sys/opencrypto/cryptodev.h b/sys/opencrypto/cryptodev.h index 3c1b7b278b3d..33ab58818f4c 100644 --- a/sys/opencrypto/cryptodev.h +++ b/sys/opencrypto/cryptodev.h @@ -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) diff --git a/sys/opencrypto/cryptosoft.c b/sys/opencrypto/cryptosoft.c index dea8499bbf58..fd83eba9f3fe 100644 --- a/sys/opencrypto/cryptosoft.c +++ b/sys/opencrypto/cryptosoft.c @@ -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); diff --git a/sys/opencrypto/xform_auth.h b/sys/opencrypto/xform_auth.h index 04654f9ada5d..bdd492bd117e 100644 --- a/sys/opencrypto/xform_auth.h +++ b/sys/opencrypto/xform_auth.h @@ -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; diff --git a/sys/opencrypto/xform_sha1.c b/sys/opencrypto/xform_sha1.c index e5d71bbfe877..44ac8c0e8b77 100644 --- a/sys/opencrypto/xform_sha1.c +++ b/sys/opencrypto/xform_sha1.c @@ -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, diff --git a/sys/opencrypto/xform_sha2.c b/sys/opencrypto/xform_sha2.c index d9cbbb585de0..0775247acb11 100644 --- a/sys/opencrypto/xform_sha2.c +++ b/sys/opencrypto/xform_sha2.c @@ -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, diff --git a/tools/tools/crypto/cryptocheck.c b/tools/tools/crypto/cryptocheck.c index 8e7629856af0..fa3459734c65 100644 --- a/tools/tools/crypto/cryptocheck.c +++ b/tools/tools/crypto/cryptocheck.c @@ -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);