forked from gopcua/opcua
/
crypto_key.go
60 lines (51 loc) · 2.34 KB
/
crypto_key.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
// Copyright 2018-2020 opcua authors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
package uapolicy
/*
Byte[] PRF(
Byte[] secret,
Byte[] seed,
Int32 length,
Int32 offset
)
Where length is the number of bytes to return and offset is a number of bytes from the beginning
of the sequence.
Where length is the number of bytes to return and offset is a number of bytes from the beginning
of the sequence.
The lengths of the keys that need to be generated depend on the SecurityPolicy used for the
channel. The following information is specified by the SecurityPolicy:
a) SigningKeyLength (from the DerivedSignatureKeyLength);
b) EncryptingKeyLength (implied by the SymmetricEncryptionAlgorithm);
c) EncryptingBlockSize (implied by the SymmetricEncryptionAlgorithm).
Name Derivation
ClientSecret The value of the ClientNonce provided in the OpenSecureChannel request.
ClientSeed The value of the ClientNonce provided in the OpenSecureChannel request.
ServerSecret The value of the ServerNonce provided in the OpenSecureChannel response.
ServerSeed The value of the ServerNonce provided in the OpenSecureChannel response.
Key Secret Seed Length Offset
ClientSigningKey ServerSecret ClientSeed SigningKeyLength 0
ClientEncryptingKey ServerSecret ClientSeed EncryptingKeyLength SigningKeyLength
ClientInitializationVector ServerSecret ClientSeed EncryptingBlockSize SigningKeyLength+ EncryptingKeyLength
ServerSigningKey ClientSecret ServerSeed SigningKeyLength 0
ServerEncryptingKey ClientSecret ServerSeed EncryptingKeyLength SigningKeyLength
ServerInitializationVector ClientSecret ServerSeed EncryptingBlockSize SigningKeyLength+ EncryptingKeyLength
*/
type derivedKeys struct {
signing, encryption, iv []byte
}
func generateKeys(hmac *HMAC, seed []byte, signingLength, encryptingLength, encryptingBlockSize int) *derivedKeys {
var p []byte
a, _ := hmac.Signature(seed)
for len(p) < signingLength+encryptingLength+encryptingBlockSize {
input := append(a, seed...)
h, _ := hmac.Signature(input)
p = append(p, h...)
a, _ = hmac.Signature(a)
}
return &derivedKeys{
signing: p[:signingLength],
encryption: p[signingLength : signingLength+encryptingLength],
iv: p[signingLength+encryptingLength : signingLength+encryptingLength+encryptingBlockSize],
}
}