Skip to content

Commit 0ebda1d

Browse files
Merge pull request #407 from WilliamTakeshi/aes-ccm-16-128-128
add support to Aes-ccm-16-128-128
2 parents 9905f5c + 7e5bbc7 commit 0ebda1d

File tree

7 files changed

+288
-48
lines changed

7 files changed

+288
-48
lines changed

crypto/lakers-crypto-cryptocell310-sys/src/lib.rs

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ impl CryptoTrait for Crypto {
8080
output
8181
}
8282

83-
fn aes_ccm_encrypt_tag_8<const N: usize>(
83+
fn aes_ccm_encrypt<const N: usize, Tag: CcmTagLen>(
8484
&mut self,
8585
key: &BytesCcmKeyLen,
8686
iv: &BytesCcmIvLen,
@@ -114,33 +114,31 @@ impl CryptoTrait for Crypto {
114114
reason = "hax won't allow creating a .as_mut_slice() method"
115115
)]
116116
output.content.as_mut_ptr(),
117-
AES_CCM_TAG_LEN as u8, // authentication tag length
117+
Tag::LEN as u8,
118118
tag.as_mut_ptr(),
119119
0 as u32, // CCM
120120
)
121121
};
122122

123-
output.extend_from_slice(&tag[..AES_CCM_TAG_LEN]).unwrap();
123+
output.extend_from_slice(&tag[..Tag::LEN]).unwrap();
124124

125125
output
126126
}
127127

128-
fn aes_ccm_decrypt_tag_8<const N: usize>(
128+
fn aes_ccm_decrypt<const N: usize, Tag: CcmTagLen>(
129129
&mut self,
130130
key: &BytesCcmKeyLen,
131131
iv: &BytesCcmIvLen,
132132
ad: &[u8],
133133
ciphertext: &[u8],
134134
) -> Result<EdhocBuffer<N>, EDHOCError> {
135135
let mut output = EdhocBuffer::new();
136-
output
137-
.extend_reserve(ciphertext.len() - AES_CCM_TAG_LEN)
138-
.unwrap();
136+
output.extend_reserve(ciphertext.len() - Tag::LEN).unwrap();
139137
let mut aesccm_key: CRYS_AESCCM_Key_t = Default::default();
140138

141-
aesccm_key[0..AES_CCM_KEY_LEN].copy_from_slice(&key[..]);
139+
aesccm_key[0..Tag::LEN].copy_from_slice(&key[..]);
142140

143-
assert!(ciphertext.len() - AES_CCM_TAG_LEN <= N);
141+
assert!(ciphertext.len() - Tag::LEN <= N);
144142

145143
#[allow(deprecated, reason = "using extend_reserve")]
146144
unsafe {
@@ -154,11 +152,11 @@ impl CryptoTrait for Crypto {
154152
ad.len() as u32,
155153
// CC_AESCCM does not really write there, it's just missing a `const`
156154
ciphertext.as_ptr() as *mut _,
157-
(ciphertext.len() - AES_CCM_TAG_LEN) as u32,
155+
(ciphertext.len() - Tag::LEN) as u32,
158156
output.content.as_mut_ptr(),
159-
AES_CCM_TAG_LEN as u8, // authentication tag length
157+
Tag::LEN as u8,
160158
// as before
161-
ciphertext[ciphertext.len() - AES_CCM_TAG_LEN..].as_ptr() as *mut _,
159+
ciphertext[ciphertext.len() - Tag::LEN..].as_ptr() as *mut _,
162160
0 as u32, // CCM
163161
) {
164162
CRYS_OK => Ok(output),
@@ -368,3 +366,20 @@ impl digest::OutputSizeUser for HashInProcessSha256 {
368366
type OutputSize = digest::typenum::U32;
369367
}
370368
impl digest::HashMarker for HashInProcessSha256 {}
369+
370+
#[cfg(test)]
371+
mod tests {
372+
use super::*;
373+
use lakers_shared::test_helper::{
374+
test_aes_ccm_roundtrip, test_aes_ccm_tag_16, test_aes_ccm_tag_8,
375+
};
376+
377+
#[test]
378+
fn test_cryptocell_aes_ccm() {
379+
test_aes_ccm_roundtrip::<Crypto, CcmTagLen8>(&mut Crypto);
380+
test_aes_ccm_roundtrip::<Crypto, CcmTagLen16>(&mut Crypto);
381+
382+
test_aes_ccm_tag_8::<Crypto>(&mut Crypto);
383+
test_aes_ccm_tag_16::<Crypto>(&mut Crypto);
384+
}
385+
}

crypto/lakers-crypto-psa/src/lib.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ impl CryptoTrait for Crypto {
8888
output
8989
}
9090

91-
fn aes_ccm_encrypt_tag_8<const N: usize>(
91+
fn aes_ccm_encrypt<const N: usize, Tag: CcmTagLen>(
9292
&mut self,
9393
key: &BytesCcmKeyLen,
9494
iv: &BytesCcmIvLen,
@@ -99,7 +99,7 @@ impl CryptoTrait for Crypto {
9999

100100
let alg = Aead::AeadWithShortenedTag {
101101
aead_alg: AeadWithDefaultLengthTag::Ccm,
102-
tag_length: 8,
102+
tag_length: Tag::LEN,
103103
};
104104
let mut usage_flags: UsageFlags = Default::default();
105105
usage_flags.set_encrypt();
@@ -116,7 +116,7 @@ impl CryptoTrait for Crypto {
116116
let my_key = key_management::import(attributes, None, &key[..]).unwrap();
117117
let mut output_buffer = EdhocBuffer::new();
118118
let full_range = output_buffer
119-
.extend_reserve(plaintext.len() + AES_CCM_TAG_LEN)
119+
.extend_reserve(plaintext.len() + Tag::LEN)
120120
.unwrap();
121121

122122
#[allow(deprecated, reason = "using extend_reserve")]
@@ -133,7 +133,7 @@ impl CryptoTrait for Crypto {
133133
output_buffer
134134
}
135135

136-
fn aes_ccm_decrypt_tag_8<const N: usize>(
136+
fn aes_ccm_decrypt<const N: usize, Tag: CcmTagLen>(
137137
&mut self,
138138
key: &BytesCcmKeyLen,
139139
iv: &BytesCcmIvLen,
@@ -144,7 +144,7 @@ impl CryptoTrait for Crypto {
144144

145145
let alg = Aead::AeadWithShortenedTag {
146146
aead_alg: AeadWithDefaultLengthTag::Ccm,
147-
tag_length: 8,
147+
tag_length: Tag::LEN,
148148
};
149149
let mut usage_flags: UsageFlags = Default::default();
150150
usage_flags.set_decrypt();
@@ -161,7 +161,7 @@ impl CryptoTrait for Crypto {
161161
let my_key = key_management::import(attributes, None, &key[..]).unwrap();
162162
let mut output_buffer = EdhocBuffer::new();
163163
let out_slice = output_buffer
164-
.extend_reserve(ciphertext.len() - AES_CCM_TAG_LEN)
164+
.extend_reserve(ciphertext.len() - Tag::LEN)
165165
.unwrap();
166166

167167
#[allow(deprecated, reason = "using extend_reserve")]
@@ -324,6 +324,9 @@ impl digest::HashMarker for BufferedHasherSha256 {}
324324
#[cfg(test)]
325325
mod tests {
326326
use super::*;
327+
use lakers_shared::test_helper::{
328+
test_aes_ccm_roundtrip, test_aes_ccm_tag_16, test_aes_ccm_tag_8,
329+
};
327330

328331
#[test]
329332
fn test_hmac_sha256() {
@@ -347,4 +350,13 @@ mod tests {
347350
let result_2 = Crypto.hmac_sha256(&MESSAGE_2, &KEY);
348351
assert_eq!(result_2, RESULT_2_TV);
349352
}
353+
354+
#[test]
355+
fn test_psa_aes_ccm() {
356+
test_aes_ccm_roundtrip::<Crypto, CcmTagLen8>(&mut Crypto);
357+
test_aes_ccm_roundtrip::<Crypto, CcmTagLen16>(&mut Crypto);
358+
359+
test_aes_ccm_tag_8::<Crypto>(&mut Crypto);
360+
test_aes_ccm_tag_16::<Crypto>(&mut Crypto);
361+
}
350362
}

crypto/lakers-crypto-rustcrypto/src/lib.rs

Lines changed: 72 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
#![no_std]
22

3+
use lakers_shared::CcmTagLen;
34
use lakers_shared::{
45
BytesCcmIvLen, BytesCcmKeyLen, BytesHashLen, BytesP256ElemLen, Crypto as CryptoTrait,
5-
EDHOCError, EDHOCSuite, EdhocBuffer, AES_CCM_TAG_LEN, MAX_SUITES_LEN,
6+
EDHOCError, EDHOCSuite, EdhocBuffer, MAX_SUITES_LEN,
67
};
78

89
use ccm::AeadInPlace;
@@ -12,6 +13,7 @@ use p256::elliptic_curve::point::DecompressPoint;
1213
use sha2::Digest;
1314

1415
type AesCcm16_64_128 = ccm::Ccm<aes::Aes128, ccm::consts::U8, ccm::consts::U13>;
16+
type AesCcm16_128_128 = ccm::Ccm<aes::Aes128, ccm::consts::U16, ccm::consts::U13>;
1517

1618
/// A type representing cryptographic operations through various RustCrypto crates (eg. [aes],
1719
/// [ccm], [p256]).
@@ -72,51 +74,81 @@ impl<Rng: rand_core::RngCore + rand_core::CryptoRng> CryptoTrait for Crypto<Rng>
7274
extracted.finalize().0.into()
7375
}
7476

75-
fn aes_ccm_encrypt_tag_8<const N: usize>(
77+
fn aes_ccm_encrypt<const N: usize, Tag: CcmTagLen>(
7678
&mut self,
7779
key: &BytesCcmKeyLen,
7880
iv: &BytesCcmIvLen,
7981
ad: &[u8],
8082
plaintext: &[u8],
8183
) -> EdhocBuffer<N> {
82-
let key = AesCcm16_64_128::new(key.into());
8384
let mut outbuffer = EdhocBuffer::new_from_slice(plaintext).unwrap();
8485
#[allow(
8586
deprecated,
8687
reason = "hax won't allow creating a .as_mut_slice() method"
8788
)]
88-
if let Ok(tag) =
89-
key.encrypt_in_place_detached(iv.into(), ad, &mut outbuffer.content[..plaintext.len()])
90-
{
91-
outbuffer.extend_from_slice(&tag).unwrap();
92-
} else {
93-
panic!("Preconfigured sizes should not allow encryption to fail")
94-
}
89+
match Tag::LEN {
90+
8 => {
91+
let enc = AesCcm16_64_128::new(key.into())
92+
.encrypt_in_place_detached(
93+
iv.into(),
94+
ad,
95+
&mut outbuffer.content[..plaintext.len()],
96+
)
97+
.expect("Preconfigured sizes should not allow encryption to fail");
98+
99+
outbuffer.extend_from_slice(&enc).unwrap()
100+
}
101+
102+
16 => {
103+
let enc = AesCcm16_128_128::new(key.into())
104+
.encrypt_in_place_detached(
105+
iv.into(),
106+
ad,
107+
&mut outbuffer.content[..plaintext.len()],
108+
)
109+
.expect("Preconfigured sizes should not allow encryption to fail");
110+
111+
outbuffer.extend_from_slice(&enc).unwrap()
112+
}
113+
114+
_ => unreachable!(), // CcmTagLen bound guarantees this
115+
};
95116
outbuffer
96117
}
97118

98-
fn aes_ccm_decrypt_tag_8<const N: usize>(
119+
fn aes_ccm_decrypt<const N: usize, Tag: CcmTagLen>(
99120
&mut self,
100121
key: &BytesCcmKeyLen,
101122
iv: &BytesCcmIvLen,
102123
ad: &[u8],
103124
ciphertext: &[u8],
104125
) -> Result<EdhocBuffer<N>, EDHOCError> {
105-
let key = AesCcm16_64_128::new(key.into());
106-
let plaintext_len = ciphertext.len() - AES_CCM_TAG_LEN;
126+
let plaintext_len = ciphertext.len() - Tag::LEN;
107127
let mut buffer = EdhocBuffer::new_from_slice(&ciphertext[..plaintext_len]).unwrap();
108128
let tag = &ciphertext[plaintext_len..];
109129
#[allow(
110130
deprecated,
111131
reason = "hax won't allow creating a .as_mut_slice() method"
112132
)]
113-
key.decrypt_in_place_detached(
114-
iv.into(),
115-
ad,
116-
&mut buffer.content[..plaintext_len],
117-
tag.into(),
118-
)
119-
.map_err(|_| EDHOCError::MacVerificationFailed)?;
133+
match Tag::LEN {
134+
8 => AesCcm16_64_128::new(key.into())
135+
.decrypt_in_place_detached(
136+
iv.into(),
137+
ad,
138+
&mut buffer.content[..plaintext_len],
139+
tag.into(),
140+
)
141+
.map_err(|_| EDHOCError::MacVerificationFailed)?,
142+
16 => AesCcm16_128_128::new(key.into())
143+
.decrypt_in_place_detached(
144+
iv.into(),
145+
ad,
146+
&mut buffer.content[..plaintext_len],
147+
tag.into(),
148+
)
149+
.map_err(|_| EDHOCError::MacVerificationFailed)?,
150+
_ => unreachable!(), // CcmTagLen bound guarantees this
151+
};
120152
Ok(buffer)
121153
}
122154

@@ -153,3 +185,23 @@ impl<Rng: rand_core::RngCore + rand_core::CryptoRng> CryptoTrait for Crypto<Rng>
153185
(private_key.into(), public_key.into())
154186
}
155187
}
188+
189+
#[cfg(test)]
190+
mod tests {
191+
use lakers_shared::test_helper::{
192+
test_aes_ccm_roundtrip, test_aes_ccm_tag_16, test_aes_ccm_tag_8,
193+
};
194+
use lakers_shared::{CcmTagLen16, CcmTagLen8};
195+
196+
use super::*;
197+
198+
#[test]
199+
fn test_rustcrypto_aes_ccm() {
200+
let mut crypto = Crypto::new(rand_core::OsRng);
201+
test_aes_ccm_roundtrip::<Crypto<rand_core::OsRng>, CcmTagLen8>(&mut crypto);
202+
test_aes_ccm_roundtrip::<Crypto<rand_core::OsRng>, CcmTagLen16>(&mut crypto);
203+
204+
test_aes_ccm_tag_8::<Crypto<rand_core::OsRng>>(&mut crypto);
205+
test_aes_ccm_tag_16::<Crypto<rand_core::OsRng>>(&mut crypto);
206+
}
207+
}

ead/lakers-ead-authz/src/device.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,12 @@ fn encrypt_enc_id<Crypto: CryptoTrait>(
107107
let enc_structure = encode_enc_structure(ss);
108108

109109
// ENC_ID = 'ciphertext' of COSE_Encrypt0
110-
crypto.aes_ccm_encrypt_tag_8(&k_1, &iv_1, &enc_structure[..], plaintext.as_slice())
110+
crypto.aes_ccm_encrypt::<MAX_MESSAGE_SIZE_LEN, CcmTagLen8>(
111+
&k_1,
112+
&iv_1,
113+
&enc_structure[..],
114+
plaintext.as_slice(),
115+
)
111116
}
112117

113118
fn encode_ead_1_value(loc_w: &EdhocMessageBuffer, enc_id: &EdhocMessageBuffer) -> EADBuffer {

ead/lakers-ead-authz/src/server.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,12 @@ fn decrypt_enc_id<Crypto: CryptoTrait>(
139139
let enc_structure = encode_enc_structure(ss);
140140

141141
// ENC_ID = 'ciphertext' of COSE_Encrypt0
142-
crypto.aes_ccm_decrypt_tag_8(&k_1, &iv_1, &enc_structure[..], enc_id.as_slice())
142+
crypto.aes_ccm_decrypt::<MAX_MESSAGE_SIZE_LEN, CcmTagLen8>(
143+
&k_1,
144+
&iv_1,
145+
&enc_structure[..],
146+
enc_id.as_slice(),
147+
)
143148
}
144149

145150
fn decode_id_u(id_u_bstr: EdhocMessageBuffer) -> Result<EdhocMessageBuffer, EDHOCError> {

lib/src/edhoc.rs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -681,8 +681,13 @@ fn encrypt_message_3(
681681

682682
let (k_3, iv_3) = compute_k_3_iv_3(crypto, prk_3e2m, th_3);
683683

684-
let ciphertext_3: BufferCiphertext3 =
685-
crypto.aes_ccm_encrypt_tag_8(&k_3, &iv_3, &enc_structure[..], plaintext_3.as_slice());
684+
let ciphertext_3: BufferCiphertext3 = crypto
685+
.aes_ccm_encrypt::<MAX_MESSAGE_SIZE_LEN, CcmTagLen8>(
686+
&k_3,
687+
&iv_3,
688+
&enc_structure[..],
689+
plaintext_3.as_slice(),
690+
);
686691

687692
output.extend_from_slice(ciphertext_3.as_slice()).unwrap();
688693

@@ -724,7 +729,12 @@ fn decrypt_message_3(
724729

725730
let enc_structure = encode_enc_structure(th_3);
726731

727-
crypto.aes_ccm_decrypt_tag_8(&k_3, &iv_3, &enc_structure, ciphertext_3.as_slice())
732+
crypto.aes_ccm_decrypt::<MAX_MESSAGE_SIZE_LEN, CcmTagLen8>(
733+
&k_3,
734+
&iv_3,
735+
&enc_structure,
736+
ciphertext_3.as_slice(),
737+
)
728738
}
729739

730740
fn encrypt_message_4(
@@ -751,8 +761,13 @@ fn encrypt_message_4(
751761

752762
let (k_4, iv_4) = compute_k_4_iv_4(crypto, prk_4e3m, th_4);
753763

754-
let ciphertext_4: BufferCiphertext4 =
755-
crypto.aes_ccm_encrypt_tag_8(&k_4, &iv_4, &enc_structure[..], plaintext_4.as_slice());
764+
let ciphertext_4: BufferCiphertext4 = crypto
765+
.aes_ccm_encrypt::<MAX_MESSAGE_SIZE_LEN, CcmTagLen8>(
766+
&k_4,
767+
&iv_4,
768+
&enc_structure[..],
769+
plaintext_4.as_slice(),
770+
);
756771

757772
output.extend_from_slice(ciphertext_4.as_slice()).unwrap();
758773

@@ -794,7 +809,12 @@ fn decrypt_message_4(
794809

795810
let enc_structure = encode_enc_structure(th_4);
796811

797-
crypto.aes_ccm_decrypt_tag_8(&k_4, &iv_4, &enc_structure, ciphertext_4.as_slice())
812+
crypto.aes_ccm_decrypt::<MAX_MESSAGE_SIZE_LEN, CcmTagLen8>(
813+
&k_4,
814+
&iv_4,
815+
&enc_structure,
816+
ciphertext_4.as_slice(),
817+
)
798818
}
799819

800820
// output must hold id_cred.len() + cred.len()

0 commit comments

Comments
 (0)