From e5dac4735367737003ede0a936a30a5a9bf9c7b3 Mon Sep 17 00:00:00 2001 From: Vitaly Isaev Date: Wed, 7 Aug 2019 19:49:20 +0300 Subject: [PATCH] UCS-7462 | feat: check if hash function is supported by the current version of OpenSSL --- digest_computer.go | 2 +- evp_md.go | 125 ++++++++++++++++++++++++++++++++++++++++++++- shim.c | 29 ----------- 3 files changed, 125 insertions(+), 31 deletions(-) diff --git a/digest_computer.go b/digest_computer.go index 349c6e25..e787f9a5 100644 --- a/digest_computer.go +++ b/digest_computer.go @@ -41,7 +41,7 @@ func (s *DigestComputer) Close() { } func (s *DigestComputer) Reset() error { - if 1 != C.X_EVP_DigestInit_ex(s.ctx, s.evpMD.fp(), engineRef(s.engine)) { + if 1 != C.X_EVP_DigestInit_ex(s.ctx, s.evpMD.c(), engineRef(s.engine)) { return fmt.Errorf("openssl: %v: cannot init evpMD ctx", s.evpMD.String()) } return nil diff --git a/evp_md.go b/evp_md.go index 5a26df3c..d0d0b8ae 100644 --- a/evp_md.go +++ b/evp_md.go @@ -1,8 +1,10 @@ package openssl +// #include "openssl/opensslv.h" // #include "shim.h" import "C" +// EVP_MD represents hash function implemented by OpenSSL type EVP_MD int const ( @@ -32,8 +34,10 @@ const ( EVP_SHAKE128 EVP_SHAKE256 EVP_SM3 + EVP_WHIRLPOOL ) +// Size returns the size of the digest func (evp EVP_MD) Size() int { var bits int switch evp { @@ -83,6 +87,7 @@ func (evp EVP_MD) Size() int { return bits / 8 } +// Size returns hash function block size in bytes func (evp EVP_MD) BlockSize() int { var bits int switch evp { @@ -181,7 +186,125 @@ func (evp EVP_MD) String() string { } } -func (evp EVP_MD) fp() (evpMD *C.EVP_MD) { + +/* +OpenSSL compatibility table: + +1.1.1 -> 0x1010100fL +1.1.0 -> 0x1010000fL + +Digest 1.0.2 1.1.0 1.1.1 +BLAKE2B512 - + + +BLAKE2S256 - + + +GOST - + + +MD2 - + + +MD4 + + + +MD5 + + + +RIPEMD160 + + + +SHA1 + + + +SHA224 + + + +SHA256 + + + +SHA384 + + + +SHA512 + + + +SHA512-224 - - + +SHA512-256 - - + +SHA3-224 - - + +SHA3-256 - - + +SHA3-384 - - + +SHA3-512 - - + +SHAKE128 - - + +SHAKE256 - - + +SM3 - - + +WHIRLPOOL + + + +*/ + +var hashFunctionsOpenSSLv111 = map[EVP_MD]bool{ + EVP_BLAKE2B_512: true, + EVP_BLAKE2S_256: true, + EVP_GOST: true, + EVP_MD2: true, + EVP_MD4: true, + EVP_MD5: true, + EVP_RIPEMD160: true, + EVP_SHA1: true, + EVP_SHA224: true, + EVP_SHA256: true, + EVP_SHA384: true, + EVP_SHA512: true, + EVP_SHA512_224: true, + EVP_SHA512_256: true, + EVP_SHA3_224: true, + EVP_SHA3_256: true, + EVP_SHA3_384: true, + EVP_SHA3_512: true, + EVP_SHAKE128: true, + EVP_SHAKE256: true, + EVP_SM3: true, + EVP_WHIRLPOOL: true, +} + +var hashFunctionsOpenSSLv110 = map[EVP_MD]bool{ + EVP_BLAKE2B_512: true, + EVP_BLAKE2S_256: true, + EVP_GOST: true, + EVP_MD2: true, + EVP_MD4: true, + EVP_MD5: true, + EVP_RIPEMD160: true, + EVP_SHA1: true, + EVP_SHA224: true, + EVP_SHA256: true, + EVP_SHA384: true, + EVP_SHA512: true, + EVP_SHA512_224: false, + EVP_SHA512_256: false, + EVP_SHA3_224: false, + EVP_SHA3_256: false, + EVP_SHA3_384: false, + EVP_SHA3_512: false, + EVP_SHAKE128: false, + EVP_SHAKE256: false, + EVP_SM3: false, + EVP_WHIRLPOOL: true, +} + +var hashFunctionsOpenSSLv102 = map[EVP_MD]bool{ + EVP_BLAKE2B_512: false, + EVP_BLAKE2S_256: false, + EVP_GOST: false, + EVP_MD2: false, + EVP_MD4: true, + EVP_MD5: true, + EVP_RIPEMD160: true, + EVP_SHA1: true, + EVP_SHA224: true, + EVP_SHA256: true, + EVP_SHA384: true, + EVP_SHA512: true, + EVP_SHA512_224: false, + EVP_SHA512_256: false, + EVP_SHA3_224: false, + EVP_SHA3_256: false, + EVP_SHA3_384: false, + EVP_SHA3_512: false, + EVP_SHAKE128: false, + EVP_SHAKE256: false, + EVP_SM3: false, + EVP_WHIRLPOOL: true, +} + +// Supported checks if this hash function is supported by the installed version of OpenSSL +func (evp EVP_MD) Supported() bool { + if C.OPENSSL_VERSION_NUMBER >= 0x1010100f { + return hashFunctionsOpenSSLv111[evp] + } else if C.OPENSSL_VERSION_NUMBER >= 0x1010000f { + return hashFunctionsOpenSSLv110[evp] + } + return hashFunctionsOpenSSLv102[evp] +} + +// c returns pointer to the struct that is used during digest initialization +func (evp EVP_MD) c() (evpMD *C.EVP_MD) { switch evp { case EVP_BLAKE2B_512: evpMD = C.X_EVP_blake2b512() diff --git a/shim.c b/shim.c index bba99288..664f6ea6 100644 --- a/shim.c +++ b/shim.c @@ -598,35 +598,6 @@ const EVP_MD *X_EVP_md_null() { return EVP_md_null(); } -/* -1.1.1 -> 0x1010100fL -1.1.0 -> 0x1010000fL - -Digest 1.0.2 1.1.0 1.1.1 -BLAKE2B512 - + + -BLAKE2S256 - + + -GOST - + + -MD2 - + + -MD4 + + + -MD5 + + + -RIPEMD160 + + + -SHA1 + + + -SHA224 + + + -SHA256 + + + -SHA384 + + + -SHA512 + + + -SHA512-224 - - + -SHA512-256 - - + -SHA3-224 - - + -SHA3-256 - - + -SHA3-384 - - + -SHA3-512 - - + -SHAKE128 - - + -SHAKE256 - - + -SM3 - - + -WHIRLPOOL + + + -*/ - const EVP_MD *X_EVP_blake2b512() { #if OPENSSL_VERSION_NUMBER >= 0x1010000fL return EVP_blake2b512();