Skip to content

Commit f8928ca

Browse files
authored
Comprehensively cleanse temporary keys used for RSA AES wrap/unwrap (#7456)
1 parent f51df5d commit f8928ca

File tree

1 file changed

+56
-36
lines changed

1 file changed

+56
-36
lines changed

src/crypto/key_wrap.cpp

Lines changed: 56 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -93,25 +93,35 @@ namespace ccf::crypto
9393
// - Generates temporary random AES key of ulAESKeyBits length. This key is
9494
// not accessible to the user - no handle is returned.
9595
std::vector<uint8_t> taeskey(aes_key_size / CHAR_BIT);
96-
RAND_bytes(taeskey.data(), taeskey.size());
97-
98-
// - Wraps the AES key with the wrapping RSA key using CKM_RSA_PKCS_OAEP
99-
// with parameters of OAEPParams.
100-
std::vector<uint8_t> w_aeskey = wrapping_key->rsa_oaep_wrap(taeskey, label);
101-
102-
// - Wraps the target key with the temporary AES key using
103-
// CKM_AES_KEY_WRAP_PAD (RFC5649).
104-
auto aes = std::make_unique<KeyAesGcm_OpenSSL>(taeskey);
105-
std::vector<uint8_t> w_target = aes->ckm_aes_key_wrap_pad(unwrapped);
106-
107-
// - Zeroizes the temporary AES key.
108-
memset(taeskey.data(), 0, taeskey.size());
109-
110-
// - Concatenates two wrapped keys and outputs the concatenated blob.
111-
std::vector<uint8_t> r;
112-
r.insert(r.end(), w_aeskey.begin(), w_aeskey.end());
113-
r.insert(r.end(), w_target.begin(), w_target.end());
114-
return r;
96+
try
97+
{
98+
RAND_bytes(taeskey.data(), taeskey.size());
99+
100+
// - Wraps the AES key with the wrapping RSA key using CKM_RSA_PKCS_OAEP
101+
// with parameters of OAEPParams.
102+
std::vector<uint8_t> w_aeskey =
103+
wrapping_key->rsa_oaep_wrap(taeskey, label);
104+
105+
// - Wraps the target key with the temporary AES key using
106+
// CKM_AES_KEY_WRAP_PAD (RFC5649).
107+
auto aes = std::make_unique<KeyAesGcm_OpenSSL>(taeskey);
108+
std::vector<uint8_t> w_target = aes->ckm_aes_key_wrap_pad(unwrapped);
109+
110+
// - Zeroizes the temporary AES key.
111+
OPENSSL_cleanse(taeskey.data(), taeskey.size());
112+
113+
// - Concatenates two wrapped keys and outputs the concatenated blob.
114+
std::vector<uint8_t> r;
115+
r.insert(r.end(), w_aeskey.begin(), w_aeskey.end());
116+
r.insert(r.end(), w_target.begin(), w_target.end());
117+
return r;
118+
}
119+
catch (...)
120+
{
121+
// Ensure temporary key is zeroed even on exceptions
122+
OPENSSL_cleanse(taeskey.data(), taeskey.size());
123+
throw;
124+
}
115125
}
116126

117127
std::vector<uint8_t> ckm_rsa_aes_key_wrap(
@@ -149,25 +159,35 @@ namespace ccf::crypto
149159
std::vector<uint8_t> t_aeskey =
150160
wrapping_key->rsa_oaep_unwrap(w_aeskey, label);
151161

152-
if (
153-
t_aeskey.size() != AES_KEY_SIZE_128_BYTES &&
154-
t_aeskey.size() != AES_KEY_SIZE_192_BYTES &&
155-
t_aeskey.size() != AES_KEY_SIZE_256_BYTES)
162+
try
156163
{
157-
throw std::runtime_error("invalid key size");
164+
if (
165+
t_aeskey.size() != AES_KEY_SIZE_128_BYTES &&
166+
t_aeskey.size() != AES_KEY_SIZE_192_BYTES &&
167+
t_aeskey.size() != AES_KEY_SIZE_256_BYTES)
168+
{
169+
throw std::runtime_error("invalid key size");
170+
}
171+
172+
// - Un-wraps the target key from the second part with the temporary AES
173+
// key
174+
// using CKM_AES_KEY_WRAP_PAD (RFC5649).
175+
176+
auto aes = std::make_unique<KeyAesGcm_OpenSSL>(t_aeskey);
177+
std::vector<uint8_t> target = aes->ckm_aes_key_unwrap_pad(w_target);
178+
179+
// - Zeroizes the temporary AES key.
180+
OPENSSL_cleanse(t_aeskey.data(), t_aeskey.size());
181+
182+
// - Returns the handle to the newly unwrapped target key.
183+
return target;
184+
}
185+
catch (...)
186+
{
187+
// Ensure temporary key is zeroed even on exceptions
188+
OPENSSL_cleanse(t_aeskey.data(), t_aeskey.size());
189+
throw;
158190
}
159-
160-
// - Un-wraps the target key from the second part with the temporary AES key
161-
// using CKM_AES_KEY_WRAP_PAD (RFC5649).
162-
163-
auto aes = std::make_unique<KeyAesGcm_OpenSSL>(t_aeskey);
164-
std::vector<uint8_t> target = aes->ckm_aes_key_unwrap_pad(w_target);
165-
166-
// - Zeroizes the temporary AES key.
167-
memset(t_aeskey.data(), 0, t_aeskey.size());
168-
169-
// - Returns the handle to the newly unwrapped target key.
170-
return target;
171191
}
172192

173193
std::vector<uint8_t> ckm_rsa_aes_key_unwrap(

0 commit comments

Comments
 (0)