1
2
3
4
5 package hpke
6
7 import (
8 "crypto/cipher"
9 "errors"
10 "fmt"
11
12 "golang.org/x/crypto/chacha20poly1305"
13 )
14
15
16
17 type AEAD interface {
18 ID() uint16
19 keySize() int
20 nonceSize() int
21 aead(key []byte) (cipher.AEAD, error)
22 }
23
24
25
26
27
28 func NewAEAD(id uint16) (AEAD, error) {
29 switch id {
30 case 0x0001:
31 return AES128GCM(), nil
32 case 0x0002:
33 return AES256GCM(), nil
34 case 0x0003:
35 return ChaCha20Poly1305(), nil
36 case 0xFFFF:
37 return ExportOnly(), nil
38 default:
39 return nil, fmt.Errorf("unsupported AEAD %04x", id)
40 }
41 }
42
43
44 func AES128GCM() AEAD { return aes128GCM }
45
46
47 func AES256GCM() AEAD { return aes256GCM }
48
49
50 func ChaCha20Poly1305() AEAD { return chacha20poly1305AEAD }
51
52
53
54
55
56 func ExportOnly() AEAD { return exportOnlyAEAD{} }
57
58 type aead struct {
59 nK int
60 nN int
61 new func([]byte) (cipher.AEAD, error)
62 id uint16
63 }
64
65 var aes128GCM = &aead{
66 nK: 128 / 8,
67 nN: 96 / 8,
68 new: newAESGCM,
69 id: 0x0001,
70 }
71
72 var aes256GCM = &aead{
73 nK: 256 / 8,
74 nN: 96 / 8,
75 new: newAESGCM,
76 id: 0x0002,
77 }
78
79 var chacha20poly1305AEAD = &aead{
80 nK: chacha20poly1305.KeySize,
81 nN: chacha20poly1305.NonceSize,
82 new: chacha20poly1305.New,
83 id: 0x0003,
84 }
85
86 func (a *aead) ID() uint16 {
87 return a.id
88 }
89
90 func (a *aead) aead(key []byte) (cipher.AEAD, error) {
91 if len(key) != a.nK {
92 return nil, errors.New("invalid key size")
93 }
94 return a.new(key)
95 }
96
97 func (a *aead) keySize() int {
98 return a.nK
99 }
100
101 func (a *aead) nonceSize() int {
102 return a.nN
103 }
104
105 type exportOnlyAEAD struct{}
106
107 func (exportOnlyAEAD) ID() uint16 {
108 return 0xFFFF
109 }
110
111 func (exportOnlyAEAD) aead(key []byte) (cipher.AEAD, error) {
112 return nil, nil
113 }
114
115 func (exportOnlyAEAD) keySize() int {
116 return 0
117 }
118
119 func (exportOnlyAEAD) nonceSize() int {
120 return 0
121 }
122
View as plain text