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