Add SHA-512-256.

(Not wired up into all the signature verifiers because we don't need or
recommend that.)

Change-Id: Ia212a1f0e1c389a31d303e00a6fafb0ec3db7c71
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/40704
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
This commit is contained in:
Adam Langley
2020-04-15 09:10:04 -07:00
committed by CQ bot account: commit-bot@chromium.org
parent 9fc31378f0
commit 3c11bf53e9
12 changed files with 177 additions and 95 deletions
+62 -59
View File
@@ -53,6 +53,7 @@ static const MD sha224 = { "SHA224", &EVP_sha224, &SHA224 };
static const MD sha256 = { "SHA256", &EVP_sha256, &SHA256 };
static const MD sha384 = { "SHA384", &EVP_sha384, &SHA384 };
static const MD sha512 = { "SHA512", &EVP_sha512, &SHA512 };
static const MD sha512_256 = { "SHA512-256", &EVP_sha512_256, &SHA512_256 };
static const MD md5_sha1 = { "MD5-SHA1", &EVP_md5_sha1, nullptr };
struct DigestTestVector {
@@ -69,79 +70,81 @@ struct DigestTestVector {
static const DigestTestVector kTestVectors[] = {
// MD4 tests, from RFC 1320. (crypto/md4 does not provide a
// one-shot MD4 function.)
{ md4, "", 1, "31d6cfe0d16ae931b73c59d7e0c089c0" },
{ md4, "a", 1, "bde52cb31de33e46245e05fbdbd6fb24" },
{ md4, "abc", 1, "a448017aaf21d8525fc10ae87aa6729d" },
{ md4, "message digest", 1, "d9130a8164549fe818874806e1c7014b" },
{ md4, "abcdefghijklmnopqrstuvwxyz", 1,
"d79e1c308aa5bbcdeea8ed63df412da9" },
{ md4,
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 1,
"043f8582f241db351ce627e153e7f0e4" },
{ md4, "1234567890", 8, "e33b4ddc9c38f2199c3e7b164fcc0536" },
{md4, "", 1, "31d6cfe0d16ae931b73c59d7e0c089c0"},
{md4, "a", 1, "bde52cb31de33e46245e05fbdbd6fb24"},
{md4, "abc", 1, "a448017aaf21d8525fc10ae87aa6729d"},
{md4, "message digest", 1, "d9130a8164549fe818874806e1c7014b"},
{md4, "abcdefghijklmnopqrstuvwxyz", 1, "d79e1c308aa5bbcdeea8ed63df412da9"},
{md4, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 1,
"043f8582f241db351ce627e153e7f0e4"},
{md4, "1234567890", 8, "e33b4ddc9c38f2199c3e7b164fcc0536"},
// MD5 tests, from RFC 1321.
{ md5, "", 1, "d41d8cd98f00b204e9800998ecf8427e" },
{ md5, "a", 1, "0cc175b9c0f1b6a831c399e269772661" },
{ md5, "abc", 1, "900150983cd24fb0d6963f7d28e17f72" },
{ md5, "message digest", 1, "f96b697d7cb7938d525a2f31aaf161d0" },
{ md5, "abcdefghijklmnopqrstuvwxyz", 1,
"c3fcd3d76192e4007dfb496cca67e13b" },
{ md5,
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 1,
"d174ab98d277d9f5a5611c2c9f419d9f" },
{ md5, "1234567890", 8, "57edf4a22be3c955ac49da2e2107b67a" },
{md5, "", 1, "d41d8cd98f00b204e9800998ecf8427e"},
{md5, "a", 1, "0cc175b9c0f1b6a831c399e269772661"},
{md5, "abc", 1, "900150983cd24fb0d6963f7d28e17f72"},
{md5, "message digest", 1, "f96b697d7cb7938d525a2f31aaf161d0"},
{md5, "abcdefghijklmnopqrstuvwxyz", 1, "c3fcd3d76192e4007dfb496cca67e13b"},
{md5, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 1,
"d174ab98d277d9f5a5611c2c9f419d9f"},
{md5, "1234567890", 8, "57edf4a22be3c955ac49da2e2107b67a"},
// SHA-1 tests, from RFC 3174.
{ sha1, "abc", 1, "a9993e364706816aba3e25717850c26c9cd0d89d" },
{ sha1,
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
"84983e441c3bd26ebaae4aa1f95129e5e54670f1" },
{ sha1, "a", 1000000, "34aa973cd4c4daa4f61eeb2bdbad27316534016f" },
{ sha1,
"0123456701234567012345670123456701234567012345670123456701234567", 10,
"dea356a2cddd90c7a7ecedc5ebb563934f460452" },
{sha1, "abc", 1, "a9993e364706816aba3e25717850c26c9cd0d89d"},
{sha1, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
"84983e441c3bd26ebaae4aa1f95129e5e54670f1"},
{sha1, "a", 1000000, "34aa973cd4c4daa4f61eeb2bdbad27316534016f"},
{sha1, "0123456701234567012345670123456701234567012345670123456701234567",
10, "dea356a2cddd90c7a7ecedc5ebb563934f460452"},
// SHA-224 tests, from RFC 3874.
{ sha224, "abc", 1,
"23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7" },
{ sha224,
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
"75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525" },
{ sha224,
"a", 1000000,
"20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67" },
{sha224, "abc", 1,
"23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7"},
{sha224, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
"75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525"},
{sha224, "a", 1000000,
"20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67"},
// SHA-256 tests, from NIST.
{ sha256, "abc", 1,
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" },
{ sha256,
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1" },
{sha256, "abc", 1,
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"},
{sha256, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"},
// SHA-384 tests, from NIST.
{ sha384, "abc", 1,
"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed"
"8086072ba1e7cc2358baeca134c825a7" },
{ sha384,
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 1,
"09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712"
"fcc7c71a557e2db966c3e9fa91746039" },
{sha384, "abc", 1,
"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed"
"8086072ba1e7cc2358baeca134c825a7"},
{sha384,
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
1,
"09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712"
"fcc7c71a557e2db966c3e9fa91746039"},
// SHA-512 tests, from NIST.
{ sha512, "abc", 1,
"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"
"2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" },
{ sha512,
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 1,
"8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"
"501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909" },
{sha512, "abc", 1,
"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"
"2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"},
{sha512,
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
1,
"8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"
"501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909"},
// SHA-512-256 tests, from
// https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha512_256.pdf
{sha512_256, "abc", 1,
"53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23"},
{sha512_256,
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopj"
"klmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
1, "3928e184fb8690f840da3988121d31be65cb9d3ef83ee6146feac861e19b563a"},
// MD5-SHA1 tests.
{ md5_sha1, "abc", 1,
"900150983cd24fb0d6963f7d28e17f72a9993e364706816aba3e25717850c26c9cd0d89d" },
{md5_sha1, "abc", 1,
"900150983cd24fb0d6963f7d28e17f72a9993e364706816aba3e25717850c26c9cd0d89d"},
};
static void CompareDigest(const DigestTestVector *test,
+16
View File
@@ -243,6 +243,22 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha512) {
}
static void sha512_256_init(EVP_MD_CTX *ctx) {
CHECK(SHA512_256_Init(ctx->md_data));
}
DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha512_256) {
out->type = NID_sha512_256;
out->md_size = SHA512_256_DIGEST_LENGTH;
out->flags = 0;
out->init = sha512_256_init;
out->update = sha512_update;
out->final = sha512_final;
out->block_size = 128;
out->ctx_size = sizeof(SHA512_CTX);
}
typedef struct {
MD5_CTX md5;
SHA_CTX sha1;
+44 -35
View File
@@ -105,6 +105,23 @@ int SHA512_Init(SHA512_CTX *sha) {
return 1;
}
int SHA512_256_Init(SHA512_CTX *sha) {
sha->h[0] = UINT64_C(0x22312194fc2bf72c);
sha->h[1] = UINT64_C(0x9f555fa3c84c64c2);
sha->h[2] = UINT64_C(0x2393b86b6f53b151);
sha->h[3] = UINT64_C(0x963877195940eabd);
sha->h[4] = UINT64_C(0x96283ee2a88effe3);
sha->h[5] = UINT64_C(0xbe5e1e2553863992);
sha->h[6] = UINT64_C(0x2b0199fc2c85b8aa);
sha->h[7] = UINT64_C(0x0eb72ddc81c52ca2);
sha->Nl = 0;
sha->Nh = 0;
sha->num = 0;
sha->md_len = SHA512_256_DIGEST_LENGTH;
return 1;
}
uint8_t *SHA384(const uint8_t *data, size_t len,
uint8_t out[SHA384_DIGEST_LENGTH]) {
SHA512_CTX ctx;
@@ -125,6 +142,16 @@ uint8_t *SHA512(const uint8_t *data, size_t len,
return out;
}
uint8_t *SHA512_256(const uint8_t *data, size_t len,
uint8_t out[SHA512_256_DIGEST_LENGTH]) {
SHA512_CTX ctx;
SHA512_256_Init(&ctx);
SHA512_Update(&ctx, data, len);
SHA512_Final(out, &ctx);
OPENSSL_cleanse(&ctx, sizeof(ctx));
return out;
}
#if !defined(SHA512_ASM)
static void sha512_block_data_order(uint64_t *state, const uint8_t *in,
size_t num_blocks);
@@ -141,6 +168,17 @@ int SHA384_Update(SHA512_CTX *sha, const void *data, size_t len) {
return SHA512_Update(sha, data, len);
}
int SHA512_256_Update(SHA512_CTX *sha, const void *data, size_t len) {
return SHA512_Update(sha, data, len);
}
int SHA512_256_Final(uint8_t out[SHA512_256_DIGEST_LENGTH],
SHA512_CTX *sha) {
// |SHA512_256_Init| sets |sha->md_len| to |SHA512_256_DIGEST_LENGTH|, so this
// has a |smaller output.
return SHA512_Final(out, sha);
}
void SHA512_Transform(SHA512_CTX *c, const uint8_t block[SHA512_CBLOCK]) {
sha512_block_data_order(c->h, block, 1);
}
@@ -231,41 +269,12 @@ int SHA512_Final(uint8_t out[SHA512_DIGEST_LENGTH], SHA512_CTX *sha) {
return 0;
}
switch (sha->md_len) {
// Let compiler decide if it's appropriate to unroll...
case SHA384_DIGEST_LENGTH:
for (n = 0; n < SHA384_DIGEST_LENGTH / 8; n++) {
uint64_t t = sha->h[n];
*(out++) = (uint8_t)(t >> 56);
*(out++) = (uint8_t)(t >> 48);
*(out++) = (uint8_t)(t >> 40);
*(out++) = (uint8_t)(t >> 32);
*(out++) = (uint8_t)(t >> 24);
*(out++) = (uint8_t)(t >> 16);
*(out++) = (uint8_t)(t >> 8);
*(out++) = (uint8_t)(t);
}
break;
case SHA512_DIGEST_LENGTH:
for (n = 0; n < SHA512_DIGEST_LENGTH / 8; n++) {
uint64_t t = sha->h[n];
*(out++) = (uint8_t)(t >> 56);
*(out++) = (uint8_t)(t >> 48);
*(out++) = (uint8_t)(t >> 40);
*(out++) = (uint8_t)(t >> 32);
*(out++) = (uint8_t)(t >> 24);
*(out++) = (uint8_t)(t >> 16);
*(out++) = (uint8_t)(t >> 8);
*(out++) = (uint8_t)(t);
}
break;
// ... as well as make sure md_len is not abused.
default:
// TODO(davidben): This bad |md_len| case is one of the few places a
// low-level hash 'final' function can fail. This should never happen.
return 0;
assert(sha->md_len % 8 == 0);
const size_t out_words = sha->md_len / 8;
for (size_t i = 0; i < out_words; i++) {
const uint64_t t = CRYPTO_bswap8(sha->h[i]);
memcpy(out, &t, sizeof(t));
out += sizeof(t);
}
return 1;
+15 -1
View File
@@ -57,7 +57,7 @@
/* This file is generated by crypto/obj/objects.go. */
#define NUM_NID 962
#define NUM_NID 963
static const uint8_t kObjectData[] = {
/* NID_rsadsi */
@@ -7127,6 +7127,16 @@ static const uint8_t kObjectData[] = {
0x2b,
0x65,
0x6f,
/* NID_sha512_256 */
0x60,
0x86,
0x48,
0x01,
0x65,
0x03,
0x04,
0x02,
0x06,
};
static const ASN1_OBJECT kObjects[NUM_NID] = {
@@ -8770,6 +8780,7 @@ static const ASN1_OBJECT kObjects[NUM_NID] = {
{"CECPQ2", "CECPQ2", NID_CECPQ2, 0, NULL, 0},
{"ED448", "ED448", NID_ED448, 3, &kObjectData[6181], 0},
{"X448", "X448", NID_X448, 3, &kObjectData[6184], 0},
{"SHA512-256", "sha512-256", NID_sha512_256, 9, &kObjectData[6187], 0},
};
static const uint16_t kNIDsInShortNameOrder[] = {
@@ -8959,6 +8970,7 @@ static const uint16_t kNIDsInShortNameOrder[] = {
672 /* SHA256 */,
673 /* SHA384 */,
674 /* SHA512 */,
962 /* SHA512-256 */,
188 /* SMIME */,
167 /* SMIME-CAPS */,
100 /* SN */,
@@ -10632,6 +10644,7 @@ static const uint16_t kNIDsInLongNameOrder[] = {
673 /* sha384 */,
669 /* sha384WithRSAEncryption */,
674 /* sha512 */,
962 /* sha512-256 */,
670 /* sha512WithRSAEncryption */,
42 /* shaWithRSAEncryption */,
52 /* signingTime */,
@@ -11391,6 +11404,7 @@ static const uint16_t kNIDsInOIDOrder[] = {
673 /* 2.16.840.1.101.3.4.2.2 (OBJ_sha384) */,
674 /* 2.16.840.1.101.3.4.2.3 (OBJ_sha512) */,
675 /* 2.16.840.1.101.3.4.2.4 (OBJ_sha224) */,
962 /* 2.16.840.1.101.3.4.2.6 (OBJ_sha512_256) */,
802 /* 2.16.840.1.101.3.4.3.1 (OBJ_dsa_with_SHA224) */,
803 /* 2.16.840.1.101.3.4.3.2 (OBJ_dsa_with_SHA256) */,
71 /* 2.16.840.1.113730.1.1 (OBJ_netscape_cert_type) */,
+1
View File
@@ -950,3 +950,4 @@ auth_any 958
CECPQ2 959
ED448 960
X448 961
sha512_256 962
+1
View File
@@ -905,6 +905,7 @@ nist_hashalgs 1 : SHA256 : sha256
nist_hashalgs 2 : SHA384 : sha384
nist_hashalgs 3 : SHA512 : sha512
nist_hashalgs 4 : SHA224 : sha224
nist_hashalgs 6 : SHA512-256 : sha512-256
# OIDs for dsa-with-sha224 and dsa-with-sha256
!Alias dsa_with_sha2 nistAlgorithms 3
+1
View File
@@ -83,6 +83,7 @@ OPENSSL_EXPORT const EVP_MD *EVP_sha224(void);
OPENSSL_EXPORT const EVP_MD *EVP_sha256(void);
OPENSSL_EXPORT const EVP_MD *EVP_sha384(void);
OPENSSL_EXPORT const EVP_MD *EVP_sha512(void);
OPENSSL_EXPORT const EVP_MD *EVP_sha512_256(void);
// EVP_md5_sha1 is a TLS-specific |EVP_MD| which computes the concatenation of
// MD5 and SHA-1, as used in TLS 1.1 and below.
+5
View File
@@ -4246,6 +4246,11 @@ extern "C" {
#define NID_X448 961
#define OBJ_X448 1L, 3L, 101L, 111L
#define SN_sha512_256 "SHA512-256"
#define LN_sha512_256 "sha512-256"
#define NID_sha512_256 962
#define OBJ_sha512_256 2L, 16L, 840L, 1L, 101L, 3L, 4L, 2L, 6L
#if defined(__cplusplus)
} /* extern C */
+26
View File
@@ -261,6 +261,32 @@ struct sha512_state_st {
};
// SHA-512-256
//
// See https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf section 5.3.6
#define SHA512_256_DIGEST_LENGTH 32
// SHA512_256_Init initialises |sha| and returns 1.
OPENSSL_EXPORT int SHA512_256_Init(SHA512_CTX *sha);
// SHA512_256_Update adds |len| bytes from |data| to |sha| and returns 1.
OPENSSL_EXPORT int SHA512_256_Update(SHA512_CTX *sha, const void *data,
size_t len);
// SHA512_256_Final adds the final padding to |sha| and writes the resulting
// digest to |out|, which must have at least |SHA512_256_DIGEST_LENGTH| bytes of
// space. It returns one on success and zero on programmer error.
OPENSSL_EXPORT int SHA512_256_Final(uint8_t out[SHA512_256_DIGEST_LENGTH],
SHA512_CTX *sha);
// SHA512_256 writes the digest of |len| bytes from |data| to |out| and returns
// |out|. There must be at least |SHA512_256_DIGEST_LENGTH| bytes of space in
// |out|.
OPENSSL_EXPORT uint8_t *SHA512_256(const uint8_t *data, size_t len,
uint8_t out[SHA512_256_DIGEST_LENGTH]);
#if defined(__cplusplus)
} // extern C
#endif
+4
View File
@@ -474,3 +474,7 @@ bool SHA384Sum(const std::vector<std::string> &args) {
bool SHA512Sum(const std::vector<std::string> &args) {
return DigestSum(EVP_sha512(), args);
}
bool SHA512256Sum(const std::vector<std::string> &args) {
return DigestSum(EVP_sha512_256(), args);
}
+1
View File
@@ -87,6 +87,7 @@ bool SHA224Sum(const std::vector<std::string> &args);
bool SHA256Sum(const std::vector<std::string> &args);
bool SHA384Sum(const std::vector<std::string> &args);
bool SHA512Sum(const std::vector<std::string> &args);
bool SHA512256Sum(const std::vector<std::string> &args);
bool Server(const std::vector<std::string> &args);
bool Sign(const std::vector<std::string> &args);
bool Speed(const std::vector<std::string> &args);
+1
View File
@@ -58,6 +58,7 @@ static const Tool kTools[] = {
{ "sha256sum", SHA256Sum },
{ "sha384sum", SHA384Sum },
{ "sha512sum", SHA512Sum },
{ "sha512256sum", SHA512256Sum },
{ "sign", Sign },
{ "speed", Speed },
{ "", nullptr },