-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathencryption_algorithm.go
More file actions
138 lines (123 loc) · 4.58 KB
/
Copy pathencryption_algorithm.go
File metadata and controls
138 lines (123 loc) · 4.58 KB
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package fapi
import "fmt"
// KeyManagementAlgorithm is a closed set of JWE key-management
// algorithms this module supports — how the content-encryption key
// (CEK) for one encrypted token is delivered to its recipient (RFC 7518
// §4). As with SignatureAlgorithm, a JOSE "alg" header is untrusted
// input: a caller states which KeyManagementAlgorithm it expects before
// a JWE is processed, rather than trusting whatever the header claims.
type KeyManagementAlgorithm uint8
const (
_ KeyManagementAlgorithm = iota
// RSAOAEP256 is RSAES OAEP using SHA-256 and MGF1 with SHA-256
// (RFC 7518 §4.3), with a minimum 2048-bit modulus — the same
// modulus floor PS256 already requires. Go's standard library
// implements OAEP directly (crypto/rsa.EncryptOAEP/DecryptOAEP), so
// this algorithm needs no hand-rolled cryptographic primitives.
RSAOAEP256
// ECDHESA256KW is ECDH-ES using Concat KDF to derive a key-wrapping
// key, which then wraps the CEK with AES-256 Key Wrap (RFC 7518
// §4.6-4.7, RFC 3394). Unlike RSAOAEP256, this module implements
// both the Concat KDF and AES Key Wrap itself — neither is provided
// by Go's standard library — so an EC-only deployment (no RSA key
// management infrastructure) has a supported option.
ECDHESA256KW
)
// String returns the JOSE "alg" header value for a, or "" if a is not a
// recognized algorithm.
func (a KeyManagementAlgorithm) String() string {
switch a {
case RSAOAEP256:
return "RSA-OAEP-256"
case ECDHESA256KW:
return "ECDH-ES+A256KW"
default:
return ""
}
}
// IsValid reports whether a is one of the algorithms this module
// supports.
func (a KeyManagementAlgorithm) IsValid() bool {
switch a {
case RSAOAEP256, ECDHESA256KW:
return true
default:
return false
}
}
// ParseKeyManagementAlgorithm maps a JOSE "alg" header value to a
// KeyManagementAlgorithm. It rejects every value outside the closed set
// this module supports, including algorithms that are valid JOSE
// algorithms in general (e.g. "RSA-OAEP", "ECDH-ES", "dir"), for the
// same reason ParseSignatureAlgorithm does: accepting one outside this
// module's own closed set would silently downgrade the guarantees the
// rest of this module assumes.
func ParseKeyManagementAlgorithm(alg string) (KeyManagementAlgorithm, error) {
switch alg {
case "RSA-OAEP-256":
return RSAOAEP256, nil
case "ECDH-ES+A256KW":
return ECDHESA256KW, nil
default:
return 0, fmt.Errorf("fapi: unsupported key management algorithm %q", alg)
}
}
// ContentEncryptionAlgorithm is a closed set of JWE content-encryption
// algorithms this module supports — how the payload itself is encrypted
// once a CEK has been established (RFC 7518 §5).
type ContentEncryptionAlgorithm uint8
const (
_ ContentEncryptionAlgorithm = iota
// A256GCM is AES-256 in Galois/Counter Mode (RFC 7518 §5.3), an AEAD
// cipher — no separate integrity algorithm is layered on top the way
// the CBC-HMAC family requires.
A256GCM
// A256CBCHS512 is AES_256_CBC_HMAC_SHA_512 (RFC 7518 §5.2.3): a
// 64-octet CEK split into a 32-octet HMAC-SHA-512 key and a
// 32-octet AES-256 key, PKCS #7-padded CBC encryption under a
// 128-bit IV, and an authentication tag computed as HMAC-SHA-512
// over AAD || IV || ciphertext || AL (AL being the AAD's bit length
// as a 64-bit big-endian integer), truncated to the first 32
// octets. Unlike A256GCM, this is encrypt-then-MAC rather than a
// single AEAD primitive, so the tag must be verified before the
// ciphertext is ever decrypted or unpadded — see internal/jwe's own
// implementation notes for why that ordering is load-bearing, not
// stylistic.
A256CBCHS512
)
// String returns the JOSE "enc" header value for a, or "" if a is not a
// recognized algorithm.
func (a ContentEncryptionAlgorithm) String() string {
switch a {
case A256GCM:
return "A256GCM"
case A256CBCHS512:
return "A256CBC-HS512"
default:
return ""
}
}
// IsValid reports whether a is one of the algorithms this module
// supports.
func (a ContentEncryptionAlgorithm) IsValid() bool {
switch a {
case A256GCM, A256CBCHS512:
return true
default:
return false
}
}
// ParseContentEncryptionAlgorithm maps a JOSE "enc" header value to a
// ContentEncryptionAlgorithm. It rejects every value outside the closed
// set this module supports, for the same reason
// ParseKeyManagementAlgorithm does.
func ParseContentEncryptionAlgorithm(enc string) (ContentEncryptionAlgorithm, error) {
switch enc {
case "A256GCM":
return A256GCM, nil
case "A256CBC-HS512":
return A256CBCHS512, nil
default:
return 0, fmt.Errorf("fapi: unsupported content encryption algorithm %q", enc)
}
}