-
Notifications
You must be signed in to change notification settings - Fork 0
/
standard.go
88 lines (80 loc) · 2.61 KB
/
standard.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// Copyright 2019 ETH Zurich
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package protocol
import (
"errors"
"github.com/scionproto/scion/go/lib/common"
"github.com/scionproto/scion/go/lib/scrypto"
"github.com/JordiSubira/drkeymockup/drkey"
)
// TODO(juagargi) the standard derivation (in this file) and delegated one will be just
// functions: won't implement any interface in particular. The way to configure
// a new protocol will look like the SCMP or PISKES protocols: new type with their functions, and
// registration with the correct name. No configuration will be allowed to change this (the
// configuration file will not include any mapping protocol->derivation).
// Standard implements the level 2 drkey derivation from level 1, without DS.
type Standard struct{}
// DeriveLvl2 derives the level 2 DRKey without passing through a delegation secret.
func (p Standard) DeriveLvl2(meta drkey.Lvl2Meta, key drkey.Lvl1Key) (drkey.Lvl2Key, error) {
h, err := scrypto.InitMac([]byte(key.Key))
if err != nil {
return drkey.Lvl2Key{}, err
}
pLen := 0
// add to buffs in reverse order:
buffs := [][]byte{}
switch meta.KeyType {
case drkey.Host2Host:
if meta.SrcHost.Size() == 0 {
return drkey.Lvl2Key{}, errors.New("Level 2 DRKey requires a src host, but it is empty")
}
b := meta.SrcHost.Pack()
buffs = [][]byte{
b,
[]byte{byte(len(b))},
}
pLen += len(b) + 1
fallthrough
case drkey.AS2Host:
if meta.DstHost.Size() == 0 {
return drkey.Lvl2Key{}, errors.New("Level 2 DRKey requires a dst host, but it is empty")
}
b := meta.DstHost.Pack()
buffs = append(buffs,
b,
[]byte{byte(len(b))})
pLen += len(b) + 1
fallthrough
case drkey.AS2AS:
b := []byte(meta.Protocol)
buffs = append(buffs,
[]byte{byte(meta.KeyType)},
b,
[]byte{byte(len(b))})
pLen += len(b) + 2
default:
return drkey.Lvl2Key{}, common.NewBasicError("Unknown DRKey type", nil)
}
all := make([]byte, pLen)
pLen = 0
for i := len(buffs) - 1; i >= 0; i-- {
copy(all[pLen:], buffs[i])
pLen += len(buffs[i])
}
h.Write(all)
return drkey.Lvl2Key{
Lvl2Meta: meta,
Key: drkey.DRKey(h.Sum(nil)),
}, nil
}