@@ -325,6 +325,7 @@ type cipherGCM struct {
325
325
}
326
326
327
327
const (
328
+ aesBlockSize = 16
328
329
gcmTagSize = 16
329
330
gcmStandardNonceSize = 12
330
331
// TLS 1.2 additional data is constructed as:
@@ -480,6 +481,56 @@ func (g *cipherGCM) Seal(dst, nonce, plaintext, aad []byte) []byte {
480
481
return ret
481
482
}
482
483
484
+ func (g * cipherGCM ) SealWithRandomNonce (out , nonce , plaintext , aad []byte ) {
485
+ if uint64 (len (plaintext )) > uint64 ((1 << 32 )- 2 )* aesBlockSize {
486
+ panic ("crypto/cipher: message too large for GCM" )
487
+ }
488
+ if len (nonce ) != gcmStandardNonceSize {
489
+ panic ("crypto/cipher: incorrect nonce length given to GCMWithRandomNonce" )
490
+ }
491
+ if len (out ) != len (plaintext )+ gcmTagSize {
492
+ panic ("crypto/cipher: incorrect output length given to GCMWithRandomNonce" )
493
+ }
494
+ if inexactOverlap (out , plaintext ) {
495
+ panic ("crypto/cipher: invalid buffer overlap of output and input" )
496
+ }
497
+ if anyOverlap (out , aad ) {
498
+ panic ("crypto/cipher: invalid buffer overlap of output and additional data" )
499
+ }
500
+
501
+ if g .tls != cipherGCMTLSNone {
502
+ panic ("cipher: encryption failed" )
503
+ }
504
+
505
+ RandReader .Read (nonce )
506
+ ctx , err := newCipherCtx (g .c .kind , cipherModeGCM , cipherOpNone , g .c .key , nil )
507
+ if err != nil {
508
+ panic (err )
509
+ }
510
+ defer ossl .EVP_CIPHER_CTX_free (ctx )
511
+
512
+ if _ , err := ossl .EVP_EncryptInit_ex (ctx , nil , nil , nil , base (nonce )); err != nil {
513
+ panic (err )
514
+ }
515
+ var outl , discard int32
516
+ if _ , err := ossl .EVP_EncryptUpdate (ctx , nil , & discard , baseNeverEmpty (aad ), int32 (len (aad ))); err != nil {
517
+ panic (err )
518
+ }
519
+ if _ , err := ossl .EVP_EncryptUpdate (ctx , base (out ), & outl , baseNeverEmpty (plaintext ), int32 (len (plaintext ))); err != nil {
520
+ panic (err )
521
+ }
522
+ if len (plaintext ) != int (outl ) {
523
+ panic ("cipher: incorrect length returned from GCM EncryptUpdate" )
524
+ }
525
+ if _ , err := ossl .EVP_EncryptFinal_ex (ctx , base (out [outl :]), & discard ); err != nil {
526
+ panic (err )
527
+ }
528
+ if _ , err := ossl .EVP_CIPHER_CTX_ctrl (ctx , ossl .EVP_CTRL_GCM_GET_TAG , 16 , unsafe .Pointer (base (out [outl :]))); err != nil {
529
+ panic (err )
530
+ }
531
+ runtime .KeepAlive (g )
532
+ }
533
+
483
534
var errOpen = errors .New ("cipher: message authentication failed" )
484
535
485
536
func (g * cipherGCM ) Open (dst , nonce , ciphertext , aad []byte ) (_ []byte , err error ) {
0 commit comments