diff --git a/provider/ALGORITHM_SUPPORT.md b/provider/ALGORITHM_SUPPORT.md index 8e1fa1902a..be9a195c18 100644 --- a/provider/ALGORITHM_SUPPORT.md +++ b/provider/ALGORITHM_SUPPORT.md @@ -18,7 +18,7 @@ None yet. | Family | Variants | |---|---| -| SHA-2 | `SHA2-224`, `SHA2-256` | +| SHA-2 | `SHA2-224`, `SHA2-256`, `SHA2-384`, `SHA2-512`, `SHA2-512/224`, `SHA2-512/256` | ## Key Encapsulation Mechanisms (`OSSL_OP_KEM`) diff --git a/provider/backend/operations/digests/sha2.c b/provider/backend/operations/digests/sha2.c index 0f1f86d8a7..334d0a19f3 100644 --- a/provider/backend/operations/digests/sha2.c +++ b/provider/backend/operations/digests/sha2.c @@ -81,3 +81,157 @@ int awslc_prov_sha256_copy(void *dst, const void *src) { *(SHA256_CTX *)dst = *(const SHA256_CTX *)src; return 1; } + +// SHA-384 + +size_t awslc_prov_sha384_ctx_size(void) { return sizeof(SHA512_CTX); } + +size_t awslc_prov_sha384_digest_size(void) { return SHA384_DIGEST_LENGTH; } + +size_t awslc_prov_sha384_block_size(void) { return SHA384_CBLOCK; } + +int awslc_prov_sha384_init(void *ctx) { + if (ctx == NULL) { + return 0; + } + return SHA384_Init((SHA512_CTX *)ctx); +} + +int awslc_prov_sha384_update(void *ctx, const void *data, size_t len) { + if (ctx == NULL || (data == NULL && len != 0)) { + return 0; + } + return SHA384_Update((SHA512_CTX *)ctx, data, len); +} + +int awslc_prov_sha384_final(void *ctx, unsigned char *out, size_t out_size) { + if (ctx == NULL || out == NULL || out_size < SHA384_DIGEST_LENGTH) { + return 0; + } + return SHA384_Final(out, (SHA512_CTX *)ctx); +} + +int awslc_prov_sha384_copy(void *dst, const void *src) { + if (dst == NULL || src == NULL) { + return 0; + } + *(SHA512_CTX *)dst = *(const SHA512_CTX *)src; + return 1; +} + +// SHA-512 + +size_t awslc_prov_sha512_ctx_size(void) { return sizeof(SHA512_CTX); } + +size_t awslc_prov_sha512_digest_size(void) { return SHA512_DIGEST_LENGTH; } + +size_t awslc_prov_sha512_block_size(void) { return SHA512_CBLOCK; } + +int awslc_prov_sha512_init(void *ctx) { + if (ctx == NULL) { + return 0; + } + return SHA512_Init((SHA512_CTX *)ctx); +} + +int awslc_prov_sha512_update(void *ctx, const void *data, size_t len) { + if (ctx == NULL || (data == NULL && len != 0)) { + return 0; + } + return SHA512_Update((SHA512_CTX *)ctx, data, len); +} + +int awslc_prov_sha512_final(void *ctx, unsigned char *out, size_t out_size) { + if (ctx == NULL || out == NULL || out_size < SHA512_DIGEST_LENGTH) { + return 0; + } + return SHA512_Final(out, (SHA512_CTX *)ctx); +} + +int awslc_prov_sha512_copy(void *dst, const void *src) { + if (dst == NULL || src == NULL) { + return 0; + } + *(SHA512_CTX *)dst = *(const SHA512_CTX *)src; + return 1; +} + +// SHA-512/224 + +size_t awslc_prov_sha512_224_ctx_size(void) { return sizeof(SHA512_CTX); } + +size_t awslc_prov_sha512_224_digest_size(void) { + return SHA512_224_DIGEST_LENGTH; +} + +size_t awslc_prov_sha512_224_block_size(void) { return SHA512_CBLOCK; } + +int awslc_prov_sha512_224_init(void *ctx) { + if (ctx == NULL) { + return 0; + } + return SHA512_224_Init((SHA512_CTX *)ctx); +} + +int awslc_prov_sha512_224_update(void *ctx, const void *data, size_t len) { + if (ctx == NULL || (data == NULL && len != 0)) { + return 0; + } + return SHA512_224_Update((SHA512_CTX *)ctx, data, len); +} + +int awslc_prov_sha512_224_final(void *ctx, unsigned char *out, + size_t out_size) { + if (ctx == NULL || out == NULL || out_size < SHA512_224_DIGEST_LENGTH) { + return 0; + } + return SHA512_224_Final(out, (SHA512_CTX *)ctx); +} + +int awslc_prov_sha512_224_copy(void *dst, const void *src) { + if (dst == NULL || src == NULL) { + return 0; + } + *(SHA512_CTX *)dst = *(const SHA512_CTX *)src; + return 1; +} + +// SHA-512/256 + +size_t awslc_prov_sha512_256_ctx_size(void) { return sizeof(SHA512_CTX); } + +size_t awslc_prov_sha512_256_digest_size(void) { + return SHA512_256_DIGEST_LENGTH; +} + +size_t awslc_prov_sha512_256_block_size(void) { return SHA512_CBLOCK; } + +int awslc_prov_sha512_256_init(void *ctx) { + if (ctx == NULL) { + return 0; + } + return SHA512_256_Init((SHA512_CTX *)ctx); +} + +int awslc_prov_sha512_256_update(void *ctx, const void *data, size_t len) { + if (ctx == NULL || (data == NULL && len != 0)) { + return 0; + } + return SHA512_256_Update((SHA512_CTX *)ctx, data, len); +} + +int awslc_prov_sha512_256_final(void *ctx, unsigned char *out, + size_t out_size) { + if (ctx == NULL || out == NULL || out_size < SHA512_256_DIGEST_LENGTH) { + return 0; + } + return SHA512_256_Final(out, (SHA512_CTX *)ctx); +} + +int awslc_prov_sha512_256_copy(void *dst, const void *src) { + if (dst == NULL || src == NULL) { + return 0; + } + *(SHA512_CTX *)dst = *(const SHA512_CTX *)src; + return 1; +} diff --git a/provider/frontend/operations/digests/sha2.c b/provider/frontend/operations/digests/sha2.c index 1e3a513b95..9c3fa3d956 100644 --- a/provider/frontend/operations/digests/sha2.c +++ b/provider/frontend/operations/digests/sha2.c @@ -192,3 +192,191 @@ static int awslc_prov_sha256_get_params(OSSL_PARAM params[]) { } AWSLC_PROV_FIXED_DIGEST_DISPATCH_TABLE(sha256); + +// SHA-384 + +AWSLC_PROV_DECLARE_FIXED_DIGEST_SLOTS(sha384); + +static void *awslc_prov_sha384_newctx(void *provctx) { + (void)provctx; + return awslc_prov_zalloc(awslc_prov_sha384_ctx_size()); +} + +static void awslc_prov_sha384_freectx(void *dctx) { + awslc_prov_sha2_freectx(dctx, awslc_prov_sha384_ctx_size()); +} + +static void *awslc_prov_sha384_dupctx(void *dctx) { + return awslc_prov_sha2_dupctx(dctx, awslc_prov_sha384_ctx_size(), + awslc_prov_sha384_copy); +} + +static void awslc_prov_sha384_copyctx(void *outctx, void *inctx) { + awslc_prov_sha2_copyctx(outctx, inctx, awslc_prov_sha384_copy); +} + +static int awslc_prov_sha384_init_op(void *dctx, const OSSL_PARAM params[]) { + return awslc_prov_sha2_init_op(dctx, params, awslc_prov_sha384_init); +} + +static int awslc_prov_sha384_update_op(void *dctx, const unsigned char *in, + size_t inl) { + return awslc_prov_sha2_update_op(dctx, in, inl, awslc_prov_sha384_update); +} + +static int awslc_prov_sha384_final_op(void *dctx, unsigned char *out, + size_t *outl, size_t outsz) { + return awslc_prov_sha2_final_op(dctx, out, outl, outsz, + awslc_prov_sha384_final, + awslc_prov_sha384_digest_size()); +} + +static int awslc_prov_sha384_get_params(OSSL_PARAM params[]) { + return awslc_prov_sha2_get_params(params, awslc_prov_sha384_block_size(), + awslc_prov_sha384_digest_size()); +} + +AWSLC_PROV_FIXED_DIGEST_DISPATCH_TABLE(sha384); + +// SHA-512 + +AWSLC_PROV_DECLARE_FIXED_DIGEST_SLOTS(sha512); + +static void *awslc_prov_sha512_newctx(void *provctx) { + (void)provctx; + return awslc_prov_zalloc(awslc_prov_sha512_ctx_size()); +} + +static void awslc_prov_sha512_freectx(void *dctx) { + awslc_prov_sha2_freectx(dctx, awslc_prov_sha512_ctx_size()); +} + +static void *awslc_prov_sha512_dupctx(void *dctx) { + return awslc_prov_sha2_dupctx(dctx, awslc_prov_sha512_ctx_size(), + awslc_prov_sha512_copy); +} + +static void awslc_prov_sha512_copyctx(void *outctx, void *inctx) { + awslc_prov_sha2_copyctx(outctx, inctx, awslc_prov_sha512_copy); +} + +static int awslc_prov_sha512_init_op(void *dctx, const OSSL_PARAM params[]) { + return awslc_prov_sha2_init_op(dctx, params, awslc_prov_sha512_init); +} + +static int awslc_prov_sha512_update_op(void *dctx, const unsigned char *in, + size_t inl) { + return awslc_prov_sha2_update_op(dctx, in, inl, awslc_prov_sha512_update); +} + +static int awslc_prov_sha512_final_op(void *dctx, unsigned char *out, + size_t *outl, size_t outsz) { + return awslc_prov_sha2_final_op(dctx, out, outl, outsz, + awslc_prov_sha512_final, + awslc_prov_sha512_digest_size()); +} + +static int awslc_prov_sha512_get_params(OSSL_PARAM params[]) { + return awslc_prov_sha2_get_params(params, awslc_prov_sha512_block_size(), + awslc_prov_sha512_digest_size()); +} + +AWSLC_PROV_FIXED_DIGEST_DISPATCH_TABLE(sha512); + +// SHA-512/224 + +AWSLC_PROV_DECLARE_FIXED_DIGEST_SLOTS(sha512_224); + +static void *awslc_prov_sha512_224_newctx(void *provctx) { + (void)provctx; + return awslc_prov_zalloc(awslc_prov_sha512_224_ctx_size()); +} + +static void awslc_prov_sha512_224_freectx(void *dctx) { + awslc_prov_sha2_freectx(dctx, awslc_prov_sha512_224_ctx_size()); +} + +static void *awslc_prov_sha512_224_dupctx(void *dctx) { + return awslc_prov_sha2_dupctx(dctx, awslc_prov_sha512_224_ctx_size(), + awslc_prov_sha512_224_copy); +} + +static void awslc_prov_sha512_224_copyctx(void *outctx, void *inctx) { + awslc_prov_sha2_copyctx(outctx, inctx, awslc_prov_sha512_224_copy); +} + +static int awslc_prov_sha512_224_init_op(void *dctx, + const OSSL_PARAM params[]) { + return awslc_prov_sha2_init_op(dctx, params, awslc_prov_sha512_224_init); +} + +static int awslc_prov_sha512_224_update_op(void *dctx, + const unsigned char *in, + size_t inl) { + return awslc_prov_sha2_update_op(dctx, in, inl, + awslc_prov_sha512_224_update); +} + +static int awslc_prov_sha512_224_final_op(void *dctx, unsigned char *out, + size_t *outl, size_t outsz) { + return awslc_prov_sha2_final_op(dctx, out, outl, outsz, + awslc_prov_sha512_224_final, + awslc_prov_sha512_224_digest_size()); +} + +static int awslc_prov_sha512_224_get_params(OSSL_PARAM params[]) { + return awslc_prov_sha2_get_params(params, + awslc_prov_sha512_224_block_size(), + awslc_prov_sha512_224_digest_size()); +} + +AWSLC_PROV_FIXED_DIGEST_DISPATCH_TABLE(sha512_224); + +// SHA-512/256 + +AWSLC_PROV_DECLARE_FIXED_DIGEST_SLOTS(sha512_256); + +static void *awslc_prov_sha512_256_newctx(void *provctx) { + (void)provctx; + return awslc_prov_zalloc(awslc_prov_sha512_256_ctx_size()); +} + +static void awslc_prov_sha512_256_freectx(void *dctx) { + awslc_prov_sha2_freectx(dctx, awslc_prov_sha512_256_ctx_size()); +} + +static void *awslc_prov_sha512_256_dupctx(void *dctx) { + return awslc_prov_sha2_dupctx(dctx, awslc_prov_sha512_256_ctx_size(), + awslc_prov_sha512_256_copy); +} + +static void awslc_prov_sha512_256_copyctx(void *outctx, void *inctx) { + awslc_prov_sha2_copyctx(outctx, inctx, awslc_prov_sha512_256_copy); +} + +static int awslc_prov_sha512_256_init_op(void *dctx, + const OSSL_PARAM params[]) { + return awslc_prov_sha2_init_op(dctx, params, awslc_prov_sha512_256_init); +} + +static int awslc_prov_sha512_256_update_op(void *dctx, + const unsigned char *in, + size_t inl) { + return awslc_prov_sha2_update_op(dctx, in, inl, + awslc_prov_sha512_256_update); +} + +static int awslc_prov_sha512_256_final_op(void *dctx, unsigned char *out, + size_t *outl, size_t outsz) { + return awslc_prov_sha2_final_op(dctx, out, outl, outsz, + awslc_prov_sha512_256_final, + awslc_prov_sha512_256_digest_size()); +} + +static int awslc_prov_sha512_256_get_params(OSSL_PARAM params[]) { + return awslc_prov_sha2_get_params(params, + awslc_prov_sha512_256_block_size(), + awslc_prov_sha512_256_digest_size()); +} + +AWSLC_PROV_FIXED_DIGEST_DISPATCH_TABLE(sha512_256); diff --git a/provider/frontend/registry.c b/provider/frontend/registry.c index 91e6bd6012..c586ca36a6 100644 --- a/provider/frontend/registry.c +++ b/provider/frontend/registry.c @@ -29,6 +29,20 @@ static const OSSL_ALGORITHM awslc_prov_digests[] = { // PROV_NAMES_SHA2_256 AWSLC_PROV_ALG("SHA2-256:SHA-256:SHA256:2.16.840.1.101.3.4.2.1", sha256, "AWS-LC SHA2-256 implementation"), + // PROV_NAMES_SHA2_384 + AWSLC_PROV_ALG("SHA2-384:SHA-384:SHA384:2.16.840.1.101.3.4.2.2", sha384, + "AWS-LC SHA2-384 implementation"), + // PROV_NAMES_SHA2_512 + AWSLC_PROV_ALG("SHA2-512:SHA-512:SHA512:2.16.840.1.101.3.4.2.3", sha512, + "AWS-LC SHA2-512 implementation"), + // PROV_NAMES_SHA2_512_224 + AWSLC_PROV_ALG( + "SHA2-512/224:SHA-512/224:SHA512-224:2.16.840.1.101.3.4.2.5", + sha512_224, "AWS-LC SHA2-512/224 implementation"), + // PROV_NAMES_SHA2_512_256 + AWSLC_PROV_ALG( + "SHA2-512/256:SHA-512/256:SHA512-256:2.16.840.1.101.3.4.2.6", + sha512_256, "AWS-LC SHA2-512/256 implementation"), {NULL, NULL, NULL, NULL}}; const OSSL_ALGORITHM *awslc_prov_query_operation(void *provctx, diff --git a/provider/internal/backend/digests.h b/provider/internal/backend/digests.h index 81132d58ce..254b3464f3 100644 --- a/provider/internal/backend/digests.h +++ b/provider/internal/backend/digests.h @@ -44,6 +44,10 @@ extern "C" { // SHA-2, from backend/operations/digests/sha2.c. AWSLC_PROV_DECLARE_DIGEST_BACKEND(sha224); AWSLC_PROV_DECLARE_DIGEST_BACKEND(sha256); +AWSLC_PROV_DECLARE_DIGEST_BACKEND(sha384); +AWSLC_PROV_DECLARE_DIGEST_BACKEND(sha512); +AWSLC_PROV_DECLARE_DIGEST_BACKEND(sha512_224); +AWSLC_PROV_DECLARE_DIGEST_BACKEND(sha512_256); #if defined(__cplusplus) } // extern "C" diff --git a/provider/internal/frontend/digests.h b/provider/internal/frontend/digests.h index fb958096ed..40629f871a 100644 --- a/provider/internal/frontend/digests.h +++ b/provider/internal/frontend/digests.h @@ -66,6 +66,10 @@ int awslc_prov_digest_get_params(OSSL_PARAM params[], size_t block_size, // frontend/operations/digests/sha2.c AWSLC_PROV_DECLARE_DIGEST_TABLE(sha224); AWSLC_PROV_DECLARE_DIGEST_TABLE(sha256); +AWSLC_PROV_DECLARE_DIGEST_TABLE(sha384); +AWSLC_PROV_DECLARE_DIGEST_TABLE(sha512); +AWSLC_PROV_DECLARE_DIGEST_TABLE(sha512_224); +AWSLC_PROV_DECLARE_DIGEST_TABLE(sha512_256); #if defined(__cplusplus) } // extern "C" diff --git a/provider/test/backend/operations/digests/sha2_test.cc b/provider/test/backend/operations/digests/sha2_test.cc index 1f68d44cd3..fd0eb7aced 100644 --- a/provider/test/backend/operations/digests/sha2_test.cc +++ b/provider/test/backend/operations/digests/sha2_test.cc @@ -25,6 +25,30 @@ const std::vector kSha256Abc = { 0xde, 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad}; +const std::vector kSha384Abc = { + 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, 0xb5, 0xa0, 0x3d, 0x69, + 0x9a, 0xc6, 0x50, 0x07, 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63, + 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, 0x80, 0x86, 0x07, 0x2b, + 0xa1, 0xe7, 0xcc, 0x23, 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7}; + +const std::vector kSha512Abc = { + 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, + 0x49, 0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, + 0x7e, 0xa2, 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, + 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, + 0xa3, 0xfe, 0xeb, 0xbd, 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, + 0x0e, 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f}; + +const std::vector kSha512_224Abc = { + 0x46, 0x34, 0x27, 0x0f, 0x70, 0x7b, 0x6a, 0x54, 0xda, 0xae, + 0x75, 0x30, 0x46, 0x08, 0x42, 0xe2, 0x0e, 0x37, 0xed, 0x26, + 0x5c, 0xee, 0xe9, 0xa4, 0x3e, 0x89, 0x24, 0xaa}; + +const std::vector kSha512_256Abc = { + 0x53, 0x04, 0x8e, 0x26, 0x81, 0x94, 0x1e, 0xf9, 0x9b, 0x2e, 0x29, + 0xb7, 0x6b, 0x4c, 0x7d, 0xab, 0xe4, 0xc2, 0xd0, 0xc6, 0x34, 0xfc, + 0x6d, 0x46, 0xe0, 0xe2, 0xf1, 0x31, 0x07, 0xe7, 0xaf, 0x23}; + // One row per algorithm the back side wraps. struct BackendDigest { const char *name; @@ -43,6 +67,20 @@ const BackendDigest kBackendDigests[] = { {"SHA-256", awslc_prov_sha256_ctx_size, awslc_prov_sha256_digest_size, awslc_prov_sha256_init, awslc_prov_sha256_update, awslc_prov_sha256_final, &kSha256Abc}, + {"SHA-384", awslc_prov_sha384_ctx_size, awslc_prov_sha384_digest_size, + awslc_prov_sha384_init, awslc_prov_sha384_update, + awslc_prov_sha384_final, &kSha384Abc}, + {"SHA-512", awslc_prov_sha512_ctx_size, awslc_prov_sha512_digest_size, + awslc_prov_sha512_init, awslc_prov_sha512_update, + awslc_prov_sha512_final, &kSha512Abc}, + {"SHA-512/224", awslc_prov_sha512_224_ctx_size, + awslc_prov_sha512_224_digest_size, awslc_prov_sha512_224_init, + awslc_prov_sha512_224_update, awslc_prov_sha512_224_final, + &kSha512_224Abc}, + {"SHA-512/256", awslc_prov_sha512_256_ctx_size, + awslc_prov_sha512_256_digest_size, awslc_prov_sha512_256_init, + awslc_prov_sha512_256_update, awslc_prov_sha512_256_final, + &kSha512_256Abc}, }; class BackendDigestTest : public testing::TestWithParam {}; diff --git a/provider/test/frontend/operations/digests/sha2_test.cc b/provider/test/frontend/operations/digests/sha2_test.cc index 28e2443228..af6f7d0cc7 100644 --- a/provider/test/frontend/operations/digests/sha2_test.cc +++ b/provider/test/frontend/operations/digests/sha2_test.cc @@ -47,6 +47,42 @@ constexpr DigestSpec kDigests[] = { 1, "abc", "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"}, + {"SHA2-384", + {"SHA2-384", "SHA-384", "SHA384", "2.16.840.1.101.3.4.2.2"}, + 48, + 128, + 0, + 1, + "abc", + "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed" + "8086072ba1e7cc2358baeca134c825a7"}, + {"SHA2-512", + {"SHA2-512", "SHA-512", "SHA512", "2.16.840.1.101.3.4.2.3"}, + 64, + 128, + 0, + 1, + "abc", + "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" + "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"}, + {"SHA2-512/224", + {"SHA2-512/224", "SHA-512/224", "SHA512-224", + "2.16.840.1.101.3.4.2.5"}, + 28, + 128, + 0, + 1, + "abc", + "4634270f707b6a54daae7530460842e20e37ed265ceee9a43e8924aa"}, + {"SHA2-512/256", + {"SHA2-512/256", "SHA-512/256", "SHA512-256", + "2.16.840.1.101.3.4.2.6"}, + 32, + 128, + 0, + 1, + "abc", + "53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23"}, }; // Renders |len| bytes as lowercase hex so a failure names the actual digest rather