@@ -24,81 +24,87 @@ import (
2424// and applying a noescape along the way.
2525// This is all to preserve compatibility with the allocation behavior of the non-openssl implementations.
2626
27- func shaX (ch crypto.Hash , p []byte , sum []byte ) bool {
27+ func hashOneShot (ch crypto.Hash , p []byte , sum []byte ) bool {
2828 return C .go_openssl_EVP_Digest (unsafe .Pointer (& * addr (p )), C .size_t (len (p )), (* C .uchar )(unsafe .Pointer (& * addr (sum ))), nil , cryptoHashToMD (ch ), nil ) != 0
2929}
3030
31+ func MD4 (p []byte ) (sum [16 ]byte ) {
32+ if ! hashOneShot (crypto .MD4 , p , sum [:]) {
33+ panic ("openssl: MD4 failed" )
34+ }
35+ return
36+ }
37+
38+ func MD5 (p []byte ) (sum [16 ]byte ) {
39+ if ! hashOneShot (crypto .MD5 , p , sum [:]) {
40+ panic ("openssl: MD5 failed" )
41+ }
42+ return
43+ }
44+
3145func SHA1 (p []byte ) (sum [20 ]byte ) {
32- if ! shaX (crypto .SHA1 , p , sum [:]) {
46+ if ! hashOneShot (crypto .SHA1 , p , sum [:]) {
3347 panic ("openssl: SHA1 failed" )
3448 }
3549 return
3650}
3751
3852func SHA224 (p []byte ) (sum [28 ]byte ) {
39- if ! shaX (crypto .SHA224 , p , sum [:]) {
53+ if ! hashOneShot (crypto .SHA224 , p , sum [:]) {
4054 panic ("openssl: SHA224 failed" )
4155 }
4256 return
4357}
4458
4559func SHA256 (p []byte ) (sum [32 ]byte ) {
46- if ! shaX (crypto .SHA256 , p , sum [:]) {
60+ if ! hashOneShot (crypto .SHA256 , p , sum [:]) {
4761 panic ("openssl: SHA256 failed" )
4862 }
4963 return
5064}
5165
5266func SHA384 (p []byte ) (sum [48 ]byte ) {
53- if ! shaX (crypto .SHA384 , p , sum [:]) {
67+ if ! hashOneShot (crypto .SHA384 , p , sum [:]) {
5468 panic ("openssl: SHA384 failed" )
5569 }
5670 return
5771}
5872
5973func SHA512 (p []byte ) (sum [64 ]byte ) {
60- if ! shaX (crypto .SHA512 , p , sum [:]) {
74+ if ! hashOneShot (crypto .SHA512 , p , sum [:]) {
6175 panic ("openssl: SHA512 failed" )
6276 }
6377 return
6478}
6579
6680// SupportsHash returns true if a hash.Hash implementation is supported for h.
6781func SupportsHash (h crypto.Hash ) bool {
68- switch h {
69- case crypto .SHA1 , crypto .SHA224 , crypto .SHA256 , crypto .SHA384 , crypto .SHA512 :
70- return true
71- case crypto .SHA3_224 , crypto .SHA3_256 , crypto .SHA3_384 , crypto .SHA3_512 :
72- return vMajor > 1 ||
73- (vMajor >= 1 && vMinor > 1 ) ||
74- (vMajor >= 1 && vMinor >= 1 && vPatch >= 1 )
75- }
76- return false
82+ return cryptoHashToMD (h ) != nil
7783}
7884
7985func SHA3_224 (p []byte ) (sum [28 ]byte ) {
80- if ! shaX (crypto .SHA3_224 , p , sum [:]) {
86+ if ! hashOneShot (crypto .SHA3_224 , p , sum [:]) {
8187 panic ("openssl: SHA3_224 failed" )
8288 }
8389 return
8490}
8591
8692func SHA3_256 (p []byte ) (sum [32 ]byte ) {
87- if ! shaX (crypto .SHA3_256 , p , sum [:]) {
93+ if ! hashOneShot (crypto .SHA3_256 , p , sum [:]) {
8894 panic ("openssl: SHA3_256 failed" )
8995 }
9096 return
9197}
9298
9399func SHA3_384 (p []byte ) (sum [48 ]byte ) {
94- if ! shaX (crypto .SHA3_384 , p , sum [:]) {
100+ if ! hashOneShot (crypto .SHA3_384 , p , sum [:]) {
95101 panic ("openssl: SHA3_384 failed" )
96102 }
97103 return
98104}
99105
100106func SHA3_512 (p []byte ) (sum [64 ]byte ) {
101- if ! shaX (crypto .SHA3_512 , p , sum [:]) {
107+ if ! hashOneShot (crypto .SHA3_512 , p , sum [:]) {
102108 panic ("openssl: SHA3_512 failed" )
103109 }
104110 return
@@ -183,17 +189,17 @@ func (h *evpHash) BlockSize() int {
183189}
184190
185191func (h * evpHash ) sum (out []byte ) {
186- if C .go_sha_sum (h .ctx , h .ctx2 , base (out )) != 1 {
187- panic (newOpenSSLError ("go_sha_sum " ))
192+ if C .go_hash_sum (h .ctx , h .ctx2 , base (out )) != 1 {
193+ panic (newOpenSSLError ("go_hash_sum " ))
188194 }
189195 runtime .KeepAlive (h )
190196}
191197
192- // shaState returns a pointer to the internal sha structure.
198+ // hashState returns a pointer to the internal hash structure.
193199//
194200// The EVP_MD_CTX memory layout has changed in OpenSSL 3
195201// and the property holding the internal structure is no longer md_data but algctx.
196- func (h * evpHash ) shaState () unsafe.Pointer {
202+ func (h * evpHash ) hashState () unsafe.Pointer {
197203 switch vMajor {
198204 case 1 :
199205 // https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/crypto/evp/evp_local.h#L12.
@@ -217,6 +223,97 @@ func (h *evpHash) shaState() unsafe.Pointer {
217223 }
218224}
219225
226+ // NewMD4 returns a new MD4 hash.
227+ // The returned hash doesn't implement encoding.BinaryMarshaler and
228+ // encoding.BinaryUnmarshaler.
229+ func NewMD4 () hash.Hash {
230+ return & md4Hash {
231+ evpHash : newEvpHash (crypto .MD4 , 16 , 64 ),
232+ }
233+ }
234+
235+ type md4Hash struct {
236+ * evpHash
237+ out [16 ]byte
238+ }
239+
240+ func (h * md4Hash ) Sum (in []byte ) []byte {
241+ h .sum (h .out [:])
242+ return append (in , h .out [:]... )
243+ }
244+
245+ // NewMD5 returns a new MD5 hash.
246+ func NewMD5 () hash.Hash {
247+ return & md5Hash {
248+ evpHash : newEvpHash (crypto .MD5 , 16 , 64 ),
249+ }
250+ }
251+
252+ // md5State layout is taken from
253+ // https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/include/openssl/md5.h#L33.
254+ type md5State struct {
255+ h [4 ]uint32
256+ nl , nh uint32
257+ x [64 ]byte
258+ nx uint32
259+ }
260+
261+ type md5Hash struct {
262+ * evpHash
263+ out [16 ]byte
264+ }
265+
266+ func (h * md5Hash ) Sum (in []byte ) []byte {
267+ h .sum (h .out [:])
268+ return append (in , h .out [:]... )
269+ }
270+
271+ const (
272+ md5Magic = "md5\x01 "
273+ md5MarshaledSize = len (md5Magic ) + 4 * 4 + 64 + 8
274+ )
275+
276+ func (h * md5Hash ) MarshalBinary () ([]byte , error ) {
277+ d := (* md5State )(h .hashState ())
278+ if d == nil {
279+ return nil , errors .New ("crypto/md5: can't retrieve hash state" )
280+ }
281+ b := make ([]byte , 0 , md5MarshaledSize )
282+ b = append (b , md5Magic ... )
283+ b = appendUint32 (b , d .h [0 ])
284+ b = appendUint32 (b , d .h [1 ])
285+ b = appendUint32 (b , d .h [2 ])
286+ b = appendUint32 (b , d .h [3 ])
287+ b = append (b , d .x [:d .nx ]... )
288+ b = b [:len (b )+ len (d .x )- int (d .nx )] // already zero
289+ b = appendUint64 (b , uint64 (d .nl )>> 3 | uint64 (d .nh )<< 29 )
290+ return b , nil
291+ }
292+
293+ func (h * md5Hash ) UnmarshalBinary (b []byte ) error {
294+ if len (b ) < len (md5Magic ) || string (b [:len (md5Magic )]) != md5Magic {
295+ return errors .New ("crypto/md5: invalid hash state identifier" )
296+ }
297+ if len (b ) != md5MarshaledSize {
298+ return errors .New ("crypto/md5: invalid hash state size" )
299+ }
300+ d := (* md5State )(h .hashState ())
301+ if d == nil {
302+ return errors .New ("crypto/md5: can't retrieve hash state" )
303+ }
304+ b = b [len (md5Magic ):]
305+ b , d .h [0 ] = consumeUint32 (b )
306+ b , d .h [1 ] = consumeUint32 (b )
307+ b , d .h [2 ] = consumeUint32 (b )
308+ b , d .h [3 ] = consumeUint32 (b )
309+ b = b [copy (d .x [:], b ):]
310+ _ , n := consumeUint64 (b )
311+ d .nl = uint32 (n << 3 )
312+ d .nh = uint32 (n >> 29 )
313+ d .nx = uint32 (n ) % 64
314+ return nil
315+ }
316+
220317// NewSHA1 returns a new SHA1 hash.
221318func NewSHA1 () hash.Hash {
222319 return & sha1Hash {
@@ -249,7 +346,7 @@ const (
249346)
250347
251348func (h * sha1Hash ) MarshalBinary () ([]byte , error ) {
252- d := (* sha1State )(h .shaState ())
349+ d := (* sha1State )(h .hashState ())
253350 if d == nil {
254351 return nil , errors .New ("crypto/sha1: can't retrieve hash state" )
255352 }
@@ -273,7 +370,7 @@ func (h *sha1Hash) UnmarshalBinary(b []byte) error {
273370 if len (b ) != sha1MarshaledSize {
274371 return errors .New ("crypto/sha1: invalid hash state size" )
275372 }
276- d := (* sha1State )(h .shaState ())
373+ d := (* sha1State )(h .hashState ())
277374 if d == nil {
278375 return errors .New ("crypto/sha1: can't retrieve hash state" )
279376 }
@@ -341,7 +438,7 @@ type sha256State struct {
341438}
342439
343440func (h * sha224Hash ) MarshalBinary () ([]byte , error ) {
344- d := (* sha256State )(h .shaState ())
441+ d := (* sha256State )(h .hashState ())
345442 if d == nil {
346443 return nil , errors .New ("crypto/sha256: can't retrieve hash state" )
347444 }
@@ -362,7 +459,7 @@ func (h *sha224Hash) MarshalBinary() ([]byte, error) {
362459}
363460
364461func (h * sha256Hash ) MarshalBinary () ([]byte , error ) {
365- d := (* sha256State )(h .shaState ())
462+ d := (* sha256State )(h .hashState ())
366463 if d == nil {
367464 return nil , errors .New ("crypto/sha256: can't retrieve hash state" )
368465 }
@@ -389,7 +486,7 @@ func (h *sha224Hash) UnmarshalBinary(b []byte) error {
389486 if len (b ) != marshaledSize256 {
390487 return errors .New ("crypto/sha256: invalid hash state size" )
391488 }
392- d := (* sha256State )(h .shaState ())
489+ d := (* sha256State )(h .hashState ())
393490 if d == nil {
394491 return errors .New ("crypto/sha256: can't retrieve hash state" )
395492 }
@@ -417,7 +514,7 @@ func (h *sha256Hash) UnmarshalBinary(b []byte) error {
417514 if len (b ) != marshaledSize256 {
418515 return errors .New ("crypto/sha256: invalid hash state size" )
419516 }
420- d := (* sha256State )(h .shaState ())
517+ d := (* sha256State )(h .hashState ())
421518 if d == nil {
422519 return errors .New ("crypto/sha256: can't retrieve hash state" )
423520 }
@@ -490,7 +587,7 @@ const (
490587)
491588
492589func (h * sha384Hash ) MarshalBinary () ([]byte , error ) {
493- d := (* sha512State )(h .shaState ())
590+ d := (* sha512State )(h .hashState ())
494591 if d == nil {
495592 return nil , errors .New ("crypto/sha512: can't retrieve hash state" )
496593 }
@@ -511,7 +608,7 @@ func (h *sha384Hash) MarshalBinary() ([]byte, error) {
511608}
512609
513610func (h * sha512Hash ) MarshalBinary () ([]byte , error ) {
514- d := (* sha512State )(h .shaState ())
611+ d := (* sha512State )(h .hashState ())
515612 if d == nil {
516613 return nil , errors .New ("crypto/sha512: can't retrieve hash state" )
517614 }
@@ -541,7 +638,7 @@ func (h *sha384Hash) UnmarshalBinary(b []byte) error {
541638 if len (b ) != marshaledSize512 {
542639 return errors .New ("crypto/sha512: invalid hash state size" )
543640 }
544- d := (* sha512State )(h .shaState ())
641+ d := (* sha512State )(h .hashState ())
545642 if d == nil {
546643 return errors .New ("crypto/sha512: can't retrieve hash state" )
547644 }
@@ -572,7 +669,7 @@ func (h *sha512Hash) UnmarshalBinary(b []byte) error {
572669 if len (b ) != marshaledSize512 {
573670 return errors .New ("crypto/sha512: invalid hash state size" )
574671 }
575- d := (* sha512State )(h .shaState ())
672+ d := (* sha512State )(h .hashState ())
576673 if d == nil {
577674 return errors .New ("crypto/sha512: can't retrieve hash state" )
578675 }
0 commit comments