Skip to content

Commit 9ddd77a

Browse files
committed
m
1 parent 0b4564f commit 9ddd77a

File tree

16 files changed

+343
-187
lines changed

16 files changed

+343
-187
lines changed

AwsEncryptionSDK/runtimes/rust/esdk_rust/esdk/src/bin/test_vector/main.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,35 @@ enum Commands {
3030
test_name: String,
3131
},
3232
}
33-
#[tokio::main]
34-
async fn main() -> Result<()> {
33+
#[tokio::main]
34+
async fn main() -> Result<()> {
3535
let cli = Cli::parse();
3636

3737
match &cli.command {
3838
Commands::Encrypt {
3939
manifest_path,
4040
decrypt_manifest_path,
4141
test_name,
42-
} => aws_esdk::test_vectors::run_tests::encrypt_test_vectors(manifest_path, decrypt_manifest_path, test_name).await,
42+
} => {
43+
aws_esdk::test_vectors::run_tests::encrypt_test_vectors(
44+
manifest_path,
45+
decrypt_manifest_path,
46+
test_name,
47+
)
48+
.await
49+
}
4350
Commands::Decrypt {
4451
manifest_path,
4552
manifest_name,
4653
test_name,
47-
} => aws_esdk::test_vectors::run_tests::decrypt_test_vectors(manifest_path, manifest_name, test_name).await,
54+
} => {
55+
aws_esdk::test_vectors::run_tests::decrypt_test_vectors(
56+
manifest_path,
57+
manifest_name,
58+
test_name,
59+
)
60+
.await
61+
}
4862
}
4963
}
5064

AwsEncryptionSDK/runtimes/rust/esdk_rust/esdk/src/encrypt_decrypt.rs

Lines changed: 9 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,16 @@ use crate::types::EncryptionContext;
1515
use crate::types::{SafeRead, SafeWrite};
1616

1717
use aws_mpl_primitives::ecdsa_verify_context;
18-
use aws_mpl_primitives::{
19-
EcdsaSignatureAlgorithm, aes_encrypt, ecdsa_verify, generate_random_bytes,
20-
};
18+
use aws_mpl_primitives::{EcdsaSignatureAlgorithm, aes_encrypt, generate_random_bytes};
2119
use aws_mpl_rs::types::AlgorithmSuiteInfo;
2220
use aws_mpl_rs::types::cryptographic_materials_manager::CryptographicMaterialsManagerRef;
2321

2422
//= compliance/client-apis/encrypt.txt#2.4.6
2523
//= type=implication
2624
//# This
2725
//# value MUST default to 4096 bytes.
28-
pub(crate) const DEFAULT_FRAME_LENGTH: usize = 4096;
26+
pub(crate) const DEFAULT_FRAME_LENGTH: u32 = 4096;
2927

30-
// UTF-8 encoded "aws-crypto-"
3128
const RESERVED_ENCRYPTION_CONTEXT: &str = "aws-crypto-";
3229

3330
pub(crate) fn encrypt_and_serialize(
@@ -38,33 +35,34 @@ pub(crate) fn encrypt_and_serialize(
3835
dw: &mut DigestWriter,
3936
) -> Result<(), Error> {
4037
let frame_length = header.body.frame_length() as usize;
41-
// let frames = plaintext.len().div_ceil(frame_length);
4238
let iv_len = get_iv_length(&header.suite) as usize;
4339
let auth_len = get_tag_length(&header.suite) as usize;
4440
let frame_len = frame_length + iv_len + auth_len + 4;
45-
// let total_size = frames * frame_len + header.raw_header.len() + iv_len + auth_len + 128;
4641
let mut w = Vec::with_capacity(frame_len);
4742
write_bytes(&mut w, &header.raw_header)?;
4843
write_header_auth_tag(&mut w, &header.header_auth, &header.suite)?;
4944
write_bytes(out, &w)?;
5045
write_bytes(dw, &w)?;
5146

52-
// let mut n: usize = 0;
5347
let mut sequence_number = START_SEQUENCE_NUMBER;
5448
let alg = get_aes_alg(&header.suite);
5549

5650
let mut iv = vec![0; iv_len];
5751
let mut plaintext_frame = vec![0; frame_length];
5852
let mut aad = Vec::new();
5953
let mut in_size: usize;
60-
// let mut foo = 0u8;
54+
let mut next_char: Option<u8> = None;
55+
6156
loop {
6257
w.clear();
63-
// in_size = read_up_to(plaintext, &mut [foo])?;
64-
in_size = read_up_to(plaintext, &mut plaintext_frame)?;
58+
in_size = read_up_to_peek(plaintext, &mut plaintext_frame, next_char)?;
6559
if in_size != frame_length {
6660
break;
6761
}
62+
next_char = read_opt_u8(plaintext)?;
63+
if next_char.is_none() {
64+
break;
65+
}
6866
if sequence_number == ENDFRAME_SEQUENCE_NUMBER {
6967
return Err("too many frames".into());
7068
}
@@ -133,59 +131,7 @@ pub(crate) const fn ecdsa_alg(
133131
}
134132
}
135133

136-
// consume and verify signature
137-
#[allow(dead_code)]
138134
pub(crate) fn verify_signature(
139-
r: &mut dyn SafeRead,
140-
msg: &[u8],
141-
dec_mat: aws_mpl_rs::types::DecryptionMaterials,
142-
raw: &mut dyn SafeWrite,
143-
) -> Result<(), Error> {
144-
//= compliance/client-apis/decrypt.txt#2.7
145-
//= type=implication
146-
//# Otherwise this operation MUST NOT perform this
147-
//# step.
148-
if dec_mat.verification_key.is_none() {
149-
return Ok(());
150-
}
151-
152-
//= compliance/client-apis/decrypt.txt#2.7.5
153-
//# If the algorithm suite has a signature algorithm, this operation MUST
154-
//# verify the message footer using the specified signature algorithm.
155-
156-
//= compliance/client-apis/decrypt.txt#2.7
157-
//# ./framework/algorithm-
158-
//# suites.md#signature-algorithm), this operation MUST perform
159-
//# this step.
160-
161-
//= compliance/client-apis/decrypt.txt#2.7.5
162-
//# After deserializing the body, this operation MUST deserialize the
163-
//# next encrypted message bytes as the message footer (../data-format/
164-
//# message-footer.md).
165-
166-
let signature = read_seq_u16(r, raw)?;
167-
let ecdsa_params = get_ecdsa_alg(&dec_mat.algorithm_suite.unwrap().signature.unwrap())?;
168-
let data_to_sign = &msg[0..msg.len() - signature.len() - 2];
169-
//= compliance/client-apis/decrypt.txt#2.7.5
170-
//# Once the message footer is deserialized, this operation MUST use the
171-
//# signature algorithm (../framework/algorithm-suites.md#signature-
172-
//# algorithm) from the algorithm suite (../framework/algorithm-
173-
//# suites.md) in the decryption materials to verify the encrypted
174-
//# message, with the following inputs:
175-
let valid = ecdsa_verify(
176-
ecdsa_alg(ecdsa_params),
177-
dec_mat.verification_key.unwrap().as_ref(),
178-
data_to_sign,
179-
&signature,
180-
)?;
181-
182-
if !valid {
183-
return Err("InvalidSignature".into());
184-
}
185-
Ok(())
186-
}
187-
188-
pub(crate) fn verify_signature2(
189135
r: &mut dyn SafeRead,
190136
context: aws_mpl_primitives::DigestContext,
191137
dec_mat: aws_mpl_rs::types::DecryptionMaterials,
@@ -215,7 +161,6 @@ pub(crate) fn verify_signature2(
215161

216162
let signature = read_seq_u16(r, raw)?;
217163
let ecdsa_params = get_ecdsa_alg(&dec_mat.algorithm_suite.unwrap().signature.unwrap())?;
218-
// let data_to_sign = &msg[0..msg.len() - signature.len() - 2];
219164
//= compliance/client-apis/decrypt.txt#2.7.5
220165
//# Once the message footer is deserialized, this operation MUST use the
221166
//# signature algorithm (../framework/algorithm-suites.md#signature-
@@ -308,14 +253,6 @@ pub(crate) fn build_header_for_encrypt(
308253
frame_length: u32,
309254
derived_data_keys: &key_derivation::ExpandedKeyMaterial,
310255
) -> Result<HeaderInfo, Error> {
311-
// requires !suite.commitment.IDENTITY?
312-
// requires SerializableTypes.IsESDKEncryptionContext(encryptionContext)
313-
// requires suite.commitment.HKDF? ==>
314-
// && derivedDataKeys.commitmentKey.Some?
315-
// && |derivedDataKeys.commitmentKey.value| == suite.commitment.HKDF.outputKeyLength as int
316-
317-
// requires frameLength > 0
318-
319256
//= aws-encryption-sdk-specification/client-apis/encrypt.md#construct-the-header
320257
//# - [AAD](../data-format/message-header.md#aad): MUST be the serialization of the [encryption context](../framework/structures.md#encryption-context)
321258
//# in the [encryption materials](../framework/structures.md#encryption-materials),
@@ -607,8 +544,6 @@ pub(crate) fn validate_suite_data(
607544
header: &HeaderBody,
608545
expected_suite_data: &[u8],
609546
) -> Result<(), Error> {
610-
// requires suite.commitment.HKDF?
611-
612547
//= compliance/client-apis/decrypt.txt#2.7.2
613548
//# The derived commit key MUST equal the commit key stored in the message
614549
//# header.
@@ -632,23 +567,6 @@ pub(crate) fn validate_suite_data(
632567
Ok(())
633568
}
634569

635-
// pub(crate) fn read_and_decrypt_framed_message_body(
636-
// r: &mut dyn SafeRead,
637-
// header: &header::HeaderInfo,
638-
// key: &[u8],
639-
// raw: &mut dyn SafeWrite,
640-
// ) -> Result<Vec<u8>, Error> {
641-
// //= compliance/client-apis/decrypt.txt#2.7.3
642-
// //# The message header MUST be read and parsed as follows.
643-
// let message_body = read_framed_message_body(r, header, raw)?;
644-
645-
// //= compliance/client-apis/decrypt.txt#2.7.3
646-
// //# The message body MUST be read and decrypted as follows.
647-
// let plaintext = decrypt_framed_message_body(&message_body, key)?;
648-
649-
// Ok(plaintext)
650-
// }
651-
652570
pub(crate) fn read_and_decrypt_non_framed_message_body(
653571
r: &mut dyn SafeRead,
654572
header: &HeaderInfo,

AwsEncryptionSDK/runtimes/rust/esdk_rust/esdk/src/esdk_operations.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,11 @@ impl Client {
5050
let frame_length = input
5151
.frame_length
5252
.unwrap_or(encrypt_decrypt::DEFAULT_FRAME_LENGTH);
53-
let frames = input.plaintext.len().div_ceil(frame_length);
53+
let frame_length_usize = frame_length as usize;
54+
let frames = input.plaintext.len().div_ceil(frame_length_usize);
5455
let iv_len = 12_usize;
5556
let auth_len = 16_usize;
56-
let frame_len = frame_length + iv_len + auth_len + 4;
57+
let frame_len = frame_length_usize + iv_len + auth_len + 4;
5758
let header_overhead = 1024_usize;
5859
let total_size = frames * frame_len + header_overhead;
5960

@@ -110,14 +111,14 @@ async fn internal_encrypt(
110111
input_keyring: Option<aws_mpl_rs::types::keyring::KeyringRef>,
111112
input_encryption_context: Option<&EncryptionContext>,
112113
algorithm_suite_id: Option<aws_mpl_rs::types::EsdkAlgorithmSuiteId>,
113-
frame_length: Option<usize>,
114+
frame_length: Option<u32>,
114115
) -> Result<EncryptStreamOutput, Error> {
115116
//= compliance/client-apis/encrypt.txt#2.4.6
116117
//# This value
117118
//# MUST be greater than 0 and MUST NOT exceed the value 2^32 - 1.
118119
let frame_length = if let Some(in_len) = frame_length {
119120
#[allow(clippy::checked_conversions)] // u32::MAX fits in a usize in real life
120-
if in_len > 0 && in_len <= u32::MAX as usize {
121+
if in_len != 0 {
121122
in_len
122123
} else {
123124
return Err("FrameLength must be greater than 0 and less than 2^32".into());
@@ -234,7 +235,7 @@ async fn internal_encrypt(
234235
materials.encryption_context.as_ref().unwrap(),
235236
materials.required_encryption_context_keys.as_ref().unwrap(),
236237
encrypted_data_keys,
237-
frame_length as u32,
238+
frame_length,
238239
&derived_data_keys,
239240
)?;
240241
let mut dw = DigestWriter::from_old_ecdsa(suite.signature.as_ref().unwrap())?;
@@ -330,10 +331,6 @@ impl Client {
330331
}
331332
}
332333

333-
// pub encryption_context: Option<&'a EncryptionContext>,
334-
// pub keyring: Option<KeyringRef>,
335-
// pub materials_manager: Option<CryptographicMaterialsManagerRef>,
336-
337334
async fn internal_decrypt(
338335
config: &Config,
339336
ciphertext: &mut dyn SafeRead,
@@ -557,16 +554,18 @@ async fn internal_decrypt(
557554
)?
558555
}
559556
ContentType::Framed => {
560-
// if dec_mat.verification_key.is_some() && safety_needed.yes() {
561-
// return Err("Streaming Interface can return data before signature has been validated. Set `i_accept_the_danger` in the DecryptStreamInput struct if this is ok.".into());
562-
// }
563557
let fail_if_multi_frame = dec_mat.verification_key.is_some() && safety_needed.yes();
564558

565559
//= compliance/client-apis/decrypt.txt#2.7.4
566560
//# If this decryption fails, this operation MUST immediately halt and
567561
//# fail.
568562
message_body::read_and_decrypt_framed_message_body(
569-
ciphertext, plaintext, &header, &key, &mut dw, fail_if_multi_frame
563+
ciphertext,
564+
plaintext,
565+
&header,
566+
&key,
567+
&mut dw,
568+
fail_if_multi_frame,
570569
)?
571570
}
572571
};
@@ -576,7 +575,7 @@ async fn internal_decrypt(
576575
//# If this verification is not successful, this operation MUST
577576
//# immediately halt and fail.
578577
let mut noop = NoopWriter;
579-
encrypt_decrypt::verify_signature2(ciphertext, dw.context.unwrap(), dec_mat, &mut noop)?;
578+
encrypt_decrypt::verify_signature(ciphertext, dw.context.unwrap(), dec_mat, &mut noop)?;
580579
}
581580
// now that we have verified the signature, we can write the last frame of data
582581
serialize_functions::write_bytes(plaintext, &last_frame)?;

AwsEncryptionSDK/runtimes/rust/esdk_rust/esdk/src/key_derivation.rs

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,6 @@ pub(crate) struct ExpandedKeyMaterial {
1414
pub(crate) data_key: Vec<u8>,
1515
pub(crate) commitment_key: Option<Vec<u8>>,
1616
}
17-
/*
18-
requires suite.kdf.HKDF?
19-
==>
20-
&& |plaintextDataKey| == suite.kdf.HKDF.inputKeyLength as nat
21-
&& suite.kdf.HKDF.outputKeyLength == SerializableTypes.GetEncryptKeyLength(suite)
22-
23-
*/
2417

2518
fn get_kdf_outlen(suite: &AlgorithmSuiteInfo) -> Result<i32, Error> {
2619
match suite.kdf.as_ref().unwrap() {
@@ -61,19 +54,10 @@ pub(crate) async fn derive_key(
6154
if suite.message_version.unwrap() != 1 {
6255
return Err("Validation Error 5".into());
6356
}
64-
// if suite.commitment.is_some() {
65-
// return Err("Validation Error 6".into());
66-
// }
6757
if !valid_derivation_alg(suite.kdf.as_ref().unwrap(), suite, plaintext_data_key.len()) {
6858
return Err("Validation Error 7".into());
6959
}
7060

71-
// ensures res.Success? ==> |res.value.dataKey| == SerializableTypes.GetEncryptKeyLength(suite) as nat
72-
// ensures res.Success? ==> IsDerivedKey(res.value.dataKey)
73-
// ensures res.Success? ==> res.value.commitmentKey.None?
74-
// ensures res.Success? ==> suite.kdf.IDENTITY? || suite.kdf.HKDF?
75-
// ensures suite.kdf.None? ==> res.Failure?
76-
7761
//= compliance/client-apis/encrypt.txt#2.6.1
7862
//# The algorithm used to derive a data key from the
7963
//# plaintext data key MUST be the key derivation algorithm
@@ -93,7 +77,6 @@ pub(crate) async fn derive_key(
9377
commitment_key: None,
9478
}),
9579
DerivationAlgorithm::Hkdf(hkdf) => {
96-
// let hkdf_input_builder: aws_mpl_rs::aws_cryptography_primitives::types::builders::HkdfInputBuilder = aws_mpl_rs::deps::aws_cryptography_primitives::types::HkdfInput::builder()
9780
let hkdf_builder = crypto
9881
.hkdf()
9982
.digest_algorithm(hkdf.hmac.unwrap())
@@ -174,11 +157,6 @@ pub(crate) async fn expand_key_material(
174157
//# algorithm-suites.md#commit-key) MUST be derived from the plaintext
175158
//# data key using the commit key derivation (../framework/algorithm-
176159
//# suites.md#algorithm-suites-commit-key-derivation-settings).
177-
// ensures res.Success? ==>
178-
// && res.value.commitmentKey.Some?
179-
// && |res.value.commitmentKey.value| == suite.commitment.HKDF.outputKeyLength as nat
180-
181-
// ensures res.Success? ==> |res.value.dataKey| == SerializableTypes.GetEncryptKeyLength(suite) as nat
182160

183161
let (digest, commit_len) = match &suite.commitment.as_ref().unwrap() {
184162
DerivationAlgorithm::Hkdf(hkdf) => (hkdf.hmac.unwrap(), hkdf.output_key_length.unwrap()),

AwsEncryptionSDK/runtimes/rust/esdk_rust/esdk/src/message_body.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,9 @@ pub(crate) fn read_and_decrypt_framed_message_body(
151151
enc_content.len() as u64,
152152
&mut aad,
153153
);
154+
#[allow(clippy::redundant_else)]
154155
if enc_content.is_empty() {
155-
// final frame is empty, to return last full frame
156+
// final frame is empty, so return last full frame
156157
let mut empty_result = Vec::new();
157158
aes_decrypt(
158159
alg,
@@ -163,7 +164,6 @@ pub(crate) fn read_and_decrypt_framed_message_body(
163164
&aad,
164165
&mut empty_result[..],
165166
)?;
166-
return Ok(result);
167167
} else {
168168
// write previous frame's data, now that we know we have another frame.
169169
if expected_frame != START_SEQUENCE_NUMBER {
@@ -182,8 +182,8 @@ pub(crate) fn read_and_decrypt_framed_message_body(
182182
&mut result[0..enc_content.len()],
183183
)?;
184184
result.resize(enc_content.len(), 0);
185-
return Ok(result);
186185
}
186+
return Ok(result);
187187
}
188188
if seq_num != expected_frame {
189189
return Err("Sequence number out of order.".into());

0 commit comments

Comments
 (0)