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 func reverseBytes(d []byte) {
19 for i, j := 0, len(d)-1; i < j; i, j = i+1, j-1 {
20 d[i], d[j] = d[j], d[i]
24 type gostAEAD struct {
26 tlsTree *gost34112012256.TLSTree
27 cipherer func([]byte) cipher.Block
31 func (g *gostAEAD) NonceSize() int { return GOSTAEADNonceSize }
32 func (g *gostAEAD) Overhead() int { return g.aead.Overhead() }
33 func (g *gostAEAD) explicitNonceLen() int { return 0 }
35 func (g *gostAEAD) keyRefresh(nonce []byte) {
36 if len(nonce) != GOSTAEADNonceSize {
37 panic("64-bit nonce expected")
39 seqNum := binary.BigEndian.Uint64(nonce)
40 key, cached := g.tlsTree.DeriveCached(seqNum)
44 cipher := g.cipherer(key)
45 aead, err := mgm.NewMGM(cipher, cipher.BlockSize())
52 func (g *gostAEAD) xorNonce(nonce []byte) {
53 for i, b := range nonce {
54 g.nonceMask[len(g.nonceMask)-GOSTAEADNonceSize+i] ^= b
58 func (g *gostAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte {
61 ret := g.aead.Seal(out, g.nonceMask[:], plaintext, additionalData)
66 func (g *gostAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]byte, error) {
69 ret, err := g.aead.Open(out, g.nonceMask[:], ciphertext, additionalData)
76 tlsTreeParams gost34112012256.TLSTreeParams,
77 cipherer func(key []byte) cipher.Block,
78 key, nonceMask []byte,
80 if len(nonceMask) != blockSize {
81 panic("tls: internal error: wrong nonce length")
84 nonceMask: make([]byte, blockSize),
85 tlsTree: gost34112012256.NewTLSTree(tlsTreeParams, key),
88 copy(ret.nonceMask, nonceMask)
89 ret.nonceMask[0] &= 0x7F
90 ret.keyRefresh([]byte{0, 0, 0, 0, 0, 0, 0, 0})
94 func aeadGOSTR341112256WithKuznyechikMGML(key, nonceMask []byte) aead {
96 gost3412128.BlockSize,
97 gost34112012256.TLSGOSTR341112256WithKuznyechikMGML,
98 func(key []byte) cipher.Block { return gost3412128.NewCipher(key) },
103 func aeadGOSTR341112256WithMagmaMGML(key, nonceMask []byte) aead {
105 gost341264.BlockSize,
106 gost34112012256.TLSGOSTR341112256WithMagmaMGML,
107 func(key []byte) cipher.Block { return gost341264.NewCipher(key) },
112 func aeadGOSTR341112256WithKuznyechikMGMS(key, nonceMask []byte) aead {
114 gost3412128.BlockSize,
115 gost34112012256.TLSGOSTR341112256WithKuznyechikMGMS,
116 func(key []byte) cipher.Block { return gost3412128.NewCipher(key) },
121 func aeadGOSTR341112256WithMagmaMGMS(key, nonceMask []byte) aead {
123 gost341264.BlockSize,
124 gost34112012256.TLSGOSTR341112256WithMagmaMGMS,
125 func(key []byte) cipher.Block { return gost341264.NewCipher(key) },
131 gostSavedDefaultSignatureAlgorithms []SignatureScheme
132 gostSavedDefaultCipherSuites []uint16
133 gostSavedDefaultCipherSuitesNoAES []uint16
134 gostSavedCipherSuitesPreferenceOrder []uint16
135 gostSavedCipherSuitesPreferenceOrderNoAES []uint16
138 func GOSTInstallSignatureAlgorithms(sigs []SignatureScheme) {
139 if gostSavedDefaultSignatureAlgorithms == nil {
140 gostSavedDefaultSignatureAlgorithms = defaultSupportedSignatureAlgorithms
142 defaultSupportedSignatureAlgorithms = append(sigs, gostSavedDefaultSignatureAlgorithms...)
145 func GOSTInstallCipherSuites(suites []uint16) {
146 if gostSavedDefaultCipherSuites == nil {
147 gostSavedDefaultCipherSuites = defaultCipherSuitesTLS13
149 if gostSavedDefaultCipherSuitesNoAES == nil {
150 gostSavedDefaultCipherSuitesNoAES = defaultCipherSuitesTLS13NoAES
152 if gostSavedCipherSuitesPreferenceOrder == nil {
153 gostSavedCipherSuitesPreferenceOrder = cipherSuitesPreferenceOrder
155 if gostSavedCipherSuitesPreferenceOrderNoAES == nil {
156 gostSavedCipherSuitesPreferenceOrderNoAES = cipherSuitesPreferenceOrderNoAES
158 defaultCipherSuitesTLS13 = append(suites, gostSavedDefaultCipherSuites...)
159 defaultCipherSuitesTLS13NoAES = append(suites, gostSavedDefaultCipherSuitesNoAES...)
160 cipherSuitesPreferenceOrder = append(suites, gostSavedCipherSuitesPreferenceOrder...)
161 cipherSuitesPreferenceOrderNoAES = append(suites, gostSavedCipherSuitesPreferenceOrderNoAES...)
165 GOSTInstallSignatureAlgorithms([]SignatureScheme{
174 GOSTInstallCipherSuites([]uint16{
175 TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_L,
176 TLS_GOSTR341112_256_WITH_MAGMA_MGM_L,
177 TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_S,
178 TLS_GOSTR341112_256_WITH_MAGMA_MGM_S,