]> Cypherpunks.ru repositories - gogost.git/blob - gost34112012256/tlstree.go
1c81359fb869325a0480c49a70373536a7ddfb12
[gogost.git] / gost34112012256 / tlstree.go
1 // GoGOST -- Pure Go GOST cryptographic functions library
2 // Copyright (C) 2015-2019 Sergey Matveev <stargrave@stargrave.org>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, version 3 of the License.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16 package gost34112012256
17
18 import (
19         "encoding/binary"
20 )
21
22 type TLSTreeParams [3]uint64
23
24 var (
25         TLSGOSTR341112256WithMagmaCTROMAC TLSTreeParams = TLSTreeParams{
26                 binary.BigEndian.Uint64([]byte{0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00}),
27                 binary.BigEndian.Uint64([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00}),
28                 binary.BigEndian.Uint64([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00}),
29         }
30         TLSGOSTR341112256WithKuznyechikCTROMAC TLSTreeParams = TLSTreeParams{
31                 binary.BigEndian.Uint64([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00}),
32                 binary.BigEndian.Uint64([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00}),
33                 binary.BigEndian.Uint64([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0}),
34         }
35         TLSGOSTR341112256WithKuznyechikMGML TLSTreeParams = TLSTreeParams{
36                 binary.BigEndian.Uint64([]byte{0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
37                 binary.BigEndian.Uint64([]byte{0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00}),
38                 binary.BigEndian.Uint64([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00}),
39         }
40         TLSGOSTR341112256WithMagmaMGML TLSTreeParams = TLSTreeParams{
41                 binary.BigEndian.Uint64([]byte{0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
42                 binary.BigEndian.Uint64([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00}),
43                 binary.BigEndian.Uint64([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80}),
44         }
45         TLSGOSTR341112256WithKuznyechikMGMS TLSTreeParams = TLSTreeParams{
46                 binary.BigEndian.Uint64([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00}),
47                 binary.BigEndian.Uint64([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00}),
48                 binary.BigEndian.Uint64([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8}),
49         }
50         TLSGOSTR341112256WithMagmaMGMS TLSTreeParams = TLSTreeParams{
51                 binary.BigEndian.Uint64([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00}),
52                 binary.BigEndian.Uint64([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00}),
53                 binary.BigEndian.Uint64([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}),
54         }
55 )
56
57 type TLSTree struct {
58         params     TLSTreeParams
59         keyRoot    []byte
60         seqNumPrev uint64
61         seq        []byte
62         key        []byte
63 }
64
65 func NewTLSTree(params TLSTreeParams, keyRoot []byte) *TLSTree {
66         key := make([]byte, len(keyRoot))
67         copy(key, keyRoot)
68         return &TLSTree{
69                 params:  params,
70                 keyRoot: key,
71                 seq:     make([]byte, 8),
72                 key:     make([]byte, Size),
73         }
74 }
75
76 func (t *TLSTree) DeriveCached(seqNum uint64) ([]byte, bool) {
77         if seqNum > 0 &&
78                 (seqNum&t.params[0]) == ((t.seqNumPrev)&t.params[0]) &&
79                 (seqNum&t.params[1]) == ((t.seqNumPrev)&t.params[1]) &&
80                 (seqNum&t.params[2]) == ((t.seqNumPrev)&t.params[2]) {
81                 return t.key, true
82         }
83         binary.BigEndian.PutUint64(t.seq, seqNum&t.params[0])
84         kdf1 := NewKDF(t.keyRoot)
85         kdf2 := NewKDF(kdf1.Derive(t.key[:0], []byte("level1"), t.seq))
86         binary.BigEndian.PutUint64(t.seq, seqNum&t.params[1])
87         kdf3 := NewKDF(kdf2.Derive(t.key[:0], []byte("level2"), t.seq))
88         binary.BigEndian.PutUint64(t.seq, seqNum&t.params[2])
89         kdf3.Derive(t.key[:0], []byte("level3"), t.seq)
90         t.seqNumPrev = seqNum
91         return t.key, false
92 }
93
94 func (t *TLSTree) Derive(seqNum uint64) []byte {
95         keyDerived := make([]byte, Size)
96         key, _ := t.DeriveCached(seqNum)
97         copy(keyDerived, key)
98         return keyDerived
99 }