1 // Copyright (C) 2020-2023 Sergey Matveev <stargrave@rnd.stcnet.ru>
2 // Use of this source code is governed by GPLv3 licence.
10 "crypto/go.cypherpunks.ru/gogost/v5/gost34112012256"
11 "crypto/go.cypherpunks.ru/gogost/v5/gost3412128"
12 "crypto/go.cypherpunks.ru/gogost/v5/gost341264"
13 "crypto/go.cypherpunks.ru/gogost/v5/mgm"
16 const GOSTAEADNonceSize = 8
18 type gostAEAD struct {
20 tlsTree *gost34112012256.TLSTree
21 cipherer func([]byte) cipher.Block
25 func (g *gostAEAD) NonceSize() int { return GOSTAEADNonceSize }
26 func (g *gostAEAD) Overhead() int { return g.aead.Overhead() }
27 func (g *gostAEAD) explicitNonceLen() int { return 0 }
29 func (g *gostAEAD) keyRefresh(nonce []byte) {
30 if len(nonce) != GOSTAEADNonceSize {
31 panic("64-bit nonce expected")
33 seqNum := binary.BigEndian.Uint64(nonce)
34 key, cached := g.tlsTree.DeriveCached(seqNum)
38 cipher := g.cipherer(key)
39 aead, err := mgm.NewMGM(cipher, cipher.BlockSize())
46 func (g *gostAEAD) xorNonce(nonce []byte) {
47 for i, b := range nonce {
48 g.nonceMask[len(g.nonceMask)-GOSTAEADNonceSize+i] ^= b
52 func (g *gostAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte {
55 ret := g.aead.Seal(out, g.nonceMask[:], plaintext, additionalData)
60 func (g *gostAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]byte, error) {
63 ret, err := g.aead.Open(out, g.nonceMask[:], ciphertext, additionalData)
70 tlsTreeParams gost34112012256.TLSTreeParams,
71 cipherer func(key []byte) cipher.Block,
72 key, nonceMask []byte,
74 if len(nonceMask) != blockSize {
75 panic("tls: internal error: wrong nonce length")
78 nonceMask: make([]byte, blockSize),
79 tlsTree: gost34112012256.NewTLSTree(tlsTreeParams, key),
82 copy(ret.nonceMask, nonceMask)
83 ret.nonceMask[0] &= 0x7F
84 ret.keyRefresh([]byte{0, 0, 0, 0, 0, 0, 0, 0})
88 func aeadGOSTR341112256WithKuznyechikMGML(key, nonceMask []byte) aead {
90 gost3412128.BlockSize,
91 gost34112012256.TLSGOSTR341112256WithKuznyechikMGML,
92 func(key []byte) cipher.Block { return gost3412128.NewCipher(key) },
97 func aeadGOSTR341112256WithMagmaMGML(key, nonceMask []byte) aead {
100 gost34112012256.TLSGOSTR341112256WithMagmaMGML,
101 func(key []byte) cipher.Block { return gost341264.NewCipher(key) },
106 func aeadGOSTR341112256WithKuznyechikMGMS(key, nonceMask []byte) aead {
108 gost3412128.BlockSize,
109 gost34112012256.TLSGOSTR341112256WithKuznyechikMGMS,
110 func(key []byte) cipher.Block { return gost3412128.NewCipher(key) },
115 func aeadGOSTR341112256WithMagmaMGMS(key, nonceMask []byte) aead {
117 gost341264.BlockSize,
118 gost34112012256.TLSGOSTR341112256WithMagmaMGMS,
119 func(key []byte) cipher.Block { return gost341264.NewCipher(key) },
125 gostSavedDefaultSignatureAlgorithms []SignatureScheme
126 gostSavedDefaultCipherSuites []uint16
127 gostSavedDefaultCipherSuitesNoAES []uint16
128 gostSavedCipherSuitesPreferenceOrder []uint16
129 gostSavedCipherSuitesPreferenceOrderNoAES []uint16
132 func GOSTInstallSignatureAlgorithms(sigs []SignatureScheme) {
133 if gostSavedDefaultSignatureAlgorithms == nil {
134 gostSavedDefaultSignatureAlgorithms = defaultSupportedSignatureAlgorithms
136 defaultSupportedSignatureAlgorithms = append(sigs, gostSavedDefaultSignatureAlgorithms...)
139 func GOSTInstallCipherSuites(suites []uint16) {
140 if gostSavedDefaultCipherSuites == nil {
141 gostSavedDefaultCipherSuites = defaultCipherSuitesTLS13
143 if gostSavedDefaultCipherSuitesNoAES == nil {
144 gostSavedDefaultCipherSuitesNoAES = defaultCipherSuitesTLS13NoAES
146 if gostSavedCipherSuitesPreferenceOrder == nil {
147 gostSavedCipherSuitesPreferenceOrder = cipherSuitesPreferenceOrder
149 if gostSavedCipherSuitesPreferenceOrderNoAES == nil {
150 gostSavedCipherSuitesPreferenceOrderNoAES = cipherSuitesPreferenceOrderNoAES
152 defaultCipherSuitesTLS13 = append(suites, gostSavedDefaultCipherSuites...)
153 defaultCipherSuitesTLS13NoAES = append(suites, gostSavedDefaultCipherSuitesNoAES...)
154 cipherSuitesPreferenceOrder = append(suites, gostSavedCipherSuitesPreferenceOrder...)
155 cipherSuitesPreferenceOrderNoAES = append(suites, gostSavedCipherSuitesPreferenceOrderNoAES...)
159 GOSTInstallSignatureAlgorithms([]SignatureScheme{
168 GOSTInstallCipherSuites([]uint16{
169 TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_L,
170 TLS_GOSTR341112_256_WITH_MAGMA_MGM_L,
171 TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_S,
172 TLS_GOSTR341112_256_WITH_MAGMA_MGM_S,