@@ -230,6 +230,34 @@ func (h *evpHash) sum(out []byte) {
230
230
runtime .KeepAlive (h )
231
231
}
232
232
233
+ // clone returns a new evpHash object that is a deep clone of itself.
234
+ // The duplicate object contains all state and data contained in the
235
+ // original object at the point of duplication.
236
+ func (h * evpHash ) clone () (* evpHash , error ) {
237
+ ctx := C .go_openssl_EVP_MD_CTX_new ()
238
+ if ctx == nil {
239
+ return nil , newOpenSSLError ("EVP_MD_CTX_new" )
240
+ }
241
+ if C .go_openssl_EVP_MD_CTX_copy_ex (ctx , h .ctx ) != 1 {
242
+ C .go_openssl_EVP_MD_CTX_free (ctx )
243
+ return nil , newOpenSSLError ("EVP_MD_CTX_copy" )
244
+ }
245
+ ctx2 := C .go_openssl_EVP_MD_CTX_new ()
246
+ if ctx2 == nil {
247
+ C .go_openssl_EVP_MD_CTX_free (ctx )
248
+ return nil , newOpenSSLError ("EVP_MD_CTX_new" )
249
+ }
250
+ cloned := & evpHash {
251
+ ctx : ctx ,
252
+ ctx2 : ctx2 ,
253
+ size : h .size ,
254
+ blockSize : h .blockSize ,
255
+ marshallable : h .marshallable ,
256
+ }
257
+ runtime .SetFinalizer (cloned , (* evpHash ).finalize )
258
+ return cloned , nil
259
+ }
260
+
233
261
// hashState returns a pointer to the internal hash structure.
234
262
//
235
263
// The EVP_MD_CTX memory layout has changed in OpenSSL 3
@@ -280,6 +308,17 @@ func (h *md4Hash) Sum(in []byte) []byte {
280
308
return append (in , h .out [:]... )
281
309
}
282
310
311
+ // Clone returns a new [hash.Hash] object that is a deep clone of itself.
312
+ // The duplicate object contains all state and data contained in the
313
+ // original object at the point of duplication.
314
+ func (h * md4Hash ) Clone () (hash.Hash , error ) {
315
+ c , err := h .clone ()
316
+ if err != nil {
317
+ return nil , err
318
+ }
319
+ return & md4Hash {evpHash : c }, nil
320
+ }
321
+
283
322
// NewMD5 returns a new MD5 hash.
284
323
func NewMD5 () hash.Hash {
285
324
h := md5Hash {evpHash : newEvpHash (crypto .MD5 )}
@@ -308,6 +347,17 @@ func (h *md5Hash) Sum(in []byte) []byte {
308
347
return append (in , h .out [:]... )
309
348
}
310
349
350
+ // Clone returns a new [hash.Hash] object that is a deep clone of itself.
351
+ // The duplicate object contains all state and data contained in the
352
+ // original object at the point of duplication.
353
+ func (h * md5Hash ) Clone () (hash.Hash , error ) {
354
+ c , err := h .clone ()
355
+ if err != nil {
356
+ return nil , err
357
+ }
358
+ return & md5Hash {evpHash : c }, nil
359
+ }
360
+
311
361
const (
312
362
md5Magic = "md5\x01 "
313
363
md5MarshaledSize = len (md5Magic ) + 4 * 4 + 64 + 8
@@ -377,6 +427,17 @@ func (h *sha1Hash) Sum(in []byte) []byte {
377
427
return append (in , h .out [:]... )
378
428
}
379
429
430
+ // Clone returns a new [hash.Hash] object that is a deep clone of itself.
431
+ // The duplicate object contains all state and data contained in the
432
+ // original object at the point of duplication.
433
+ func (h * sha1Hash ) Clone () (hash.Hash , error ) {
434
+ c , err := h .clone ()
435
+ if err != nil {
436
+ return nil , err
437
+ }
438
+ return & sha1Hash {evpHash : c }, nil
439
+ }
440
+
380
441
// sha1State layout is taken from
381
442
// https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/include/openssl/sha.h#L34.
382
443
type sha1State struct {
@@ -457,6 +518,17 @@ func (h *sha224Hash) Sum(in []byte) []byte {
457
518
return append (in , h .out [:]... )
458
519
}
459
520
521
+ // Clone returns a new [hash.Hash] object that is a deep clone of itself.
522
+ // The duplicate object contains all state and data contained in the
523
+ // original object at the point of duplication.
524
+ func (h * sha224Hash ) Clone () (hash.Hash , error ) {
525
+ c , err := h .clone ()
526
+ if err != nil {
527
+ return nil , err
528
+ }
529
+ return & sha224Hash {evpHash : c }, nil
530
+ }
531
+
460
532
// NewSHA256 returns a new SHA256 hash.
461
533
func NewSHA256 () hash.Hash {
462
534
h := sha256Hash {evpHash : newEvpHash (crypto .SHA256 )}
@@ -476,6 +548,17 @@ func (h *sha256Hash) Sum(in []byte) []byte {
476
548
return append (in , h .out [:]... )
477
549
}
478
550
551
+ // Clone returns a new [hash.Hash] object that is a deep clone of itself.
552
+ // The duplicate object contains all state and data contained in the
553
+ // original object at the point of duplication.
554
+ func (h * sha256Hash ) Clone () (hash.Hash , error ) {
555
+ c , err := h .clone ()
556
+ if err != nil {
557
+ return nil , err
558
+ }
559
+ return & sha256Hash {evpHash : c }, nil
560
+ }
561
+
479
562
const (
480
563
magic224 = "sha\x02 "
481
564
magic256 = "sha\x03 "
@@ -616,6 +699,17 @@ func (h *sha384Hash) Sum(in []byte) []byte {
616
699
return append (in , h .out [:]... )
617
700
}
618
701
702
+ // Clone returns a new [hash.Hash] object that is a deep clone of itself.
703
+ // The duplicate object contains all state and data contained in the
704
+ // original object at the point of duplication.
705
+ func (h * sha384Hash ) Clone () (hash.Hash , error ) {
706
+ c , err := h .clone ()
707
+ if err != nil {
708
+ return nil , err
709
+ }
710
+ return & sha384Hash {evpHash : c }, nil
711
+ }
712
+
619
713
// NewSHA512 returns a new SHA512 hash.
620
714
func NewSHA512 () hash.Hash {
621
715
h := sha512Hash {evpHash : newEvpHash (crypto .SHA512 )}
@@ -635,6 +729,17 @@ func (h *sha512Hash) Sum(in []byte) []byte {
635
729
return append (in , h .out [:]... )
636
730
}
637
731
732
+ // Clone returns a new [hash.Hash] object that is a deep clone of itself.
733
+ // The duplicate object contains all state and data contained in the
734
+ // original object at the point of duplication.
735
+ func (h * sha512Hash ) Clone () (hash.Hash , error ) {
736
+ c , err := h .clone ()
737
+ if err != nil {
738
+ return nil , err
739
+ }
740
+ return & sha512Hash {evpHash : c }, nil
741
+ }
742
+
638
743
// sha512State layout is taken from
639
744
// https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/include/openssl/sha.h#L95.
640
745
type sha512State struct {
@@ -781,6 +886,17 @@ func (h *sha3_224Hash) Sum(in []byte) []byte {
781
886
return append (in , h .out [:]... )
782
887
}
783
888
889
+ // Clone returns a new [hash.Hash] object that is a deep clone of itself.
890
+ // The duplicate object contains all state and data contained in the
891
+ // original object at the point of duplication.
892
+ func (h * sha3_224Hash ) Clone () (hash.Hash , error ) {
893
+ c , err := h .clone ()
894
+ if err != nil {
895
+ return nil , err
896
+ }
897
+ return & sha3_224Hash {evpHash : c }, nil
898
+ }
899
+
784
900
// NewSHA3_256 returns a new SHA3-256 hash.
785
901
func NewSHA3_256 () hash.Hash {
786
902
return & sha3_256Hash {
@@ -798,6 +914,17 @@ func (h *sha3_256Hash) Sum(in []byte) []byte {
798
914
return append (in , h .out [:]... )
799
915
}
800
916
917
+ // Clone returns a new [hash.Hash] object that is a deep clone of itself.
918
+ // The duplicate object contains all state and data contained in the
919
+ // original object at the point of duplication.
920
+ func (h * sha3_256Hash ) Clone () (hash.Hash , error ) {
921
+ c , err := h .clone ()
922
+ if err != nil {
923
+ return nil , err
924
+ }
925
+ return & sha3_256Hash {evpHash : c }, nil
926
+ }
927
+
801
928
// NewSHA3_384 returns a new SHA3-384 hash.
802
929
func NewSHA3_384 () hash.Hash {
803
930
return & sha3_384Hash {
@@ -815,6 +942,17 @@ func (h *sha3_384Hash) Sum(in []byte) []byte {
815
942
return append (in , h .out [:]... )
816
943
}
817
944
945
+ // Clone returns a new [hash.Hash] object that is a deep clone of itself.
946
+ // The duplicate object contains all state and data contained in the
947
+ // original object at the point of duplication.
948
+ func (h * sha3_384Hash ) Clone () (hash.Hash , error ) {
949
+ c , err := h .clone ()
950
+ if err != nil {
951
+ return nil , err
952
+ }
953
+ return & sha3_384Hash {evpHash : c }, nil
954
+ }
955
+
818
956
// NewSHA3_512 returns a new SHA3-512 hash.
819
957
func NewSHA3_512 () hash.Hash {
820
958
return & sha3_512Hash {
@@ -832,6 +970,17 @@ func (h *sha3_512Hash) Sum(in []byte) []byte {
832
970
return append (in , h .out [:]... )
833
971
}
834
972
973
+ // Clone returns a new [hash.Hash] object that is a deep clone of itself.
974
+ // The duplicate object contains all state and data contained in the
975
+ // original object at the point of duplication.
976
+ func (h * sha3_512Hash ) Clone () (hash.Hash , error ) {
977
+ c , err := h .clone ()
978
+ if err != nil {
979
+ return nil , err
980
+ }
981
+ return & sha3_512Hash {evpHash : c }, nil
982
+ }
983
+
835
984
// appendUint64 appends x into b as a big endian byte sequence.
836
985
func appendUint64 (b []byte , x uint64 ) []byte {
837
986
return append (b ,
0 commit comments