/rust/registry/src/index.crates.io-1949cf8c6b5b557f/aws-lc-rs-1.14.1/src/cipher/padded.rs
Line | Count | Source |
1 | | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. |
2 | | // SPDX-License-Identifier: Apache-2.0 OR ISC |
3 | | use crate::cipher; |
4 | | use crate::cipher::key::SymmetricCipherKey; |
5 | | use crate::cipher::{ |
6 | | Algorithm, DecryptionContext, EncryptionContext, OperatingMode, UnboundCipherKey, |
7 | | MAX_CIPHER_BLOCK_LEN, |
8 | | }; |
9 | | use crate::error::Unspecified; |
10 | | use core::fmt::Debug; |
11 | | |
12 | | /// The cipher block padding strategy. |
13 | | #[non_exhaustive] |
14 | | #[derive(Debug, PartialEq, Eq, Clone, Copy)] |
15 | | pub(crate) enum PaddingStrategy { |
16 | | /// ISO 10126 padding. For compatibility purposes only. Applies non-random PKCS7 padding. |
17 | | ISO10126, |
18 | | /// PKCS#7 Padding. ([See RFC 5652](https://datatracker.ietf.org/doc/html/rfc5652#section-6.3)) |
19 | | PKCS7, |
20 | | } |
21 | | |
22 | | impl PaddingStrategy { |
23 | 0 | fn add_padding<InOut>(self, block_len: usize, in_out: &mut InOut) -> Result<(), Unspecified> |
24 | 0 | where |
25 | 0 | InOut: AsMut<[u8]> + for<'in_out> Extend<&'in_out u8>, |
26 | | { |
27 | 0 | match self { |
28 | | // PKCS7 padding can be unpadded as ISO 10126 padding |
29 | | PaddingStrategy::ISO10126 | PaddingStrategy::PKCS7 => { |
30 | 0 | let mut padding_buffer = [0u8; MAX_CIPHER_BLOCK_LEN]; |
31 | | |
32 | 0 | let in_out_len = in_out.as_mut().len(); |
33 | | // This implements PKCS#7 padding scheme, used by aws-lc if we were using EVP_CIPHER API's |
34 | 0 | let remainder = in_out_len % block_len; |
35 | 0 | let padding_size = block_len - remainder; |
36 | 0 | let v: u8 = padding_size.try_into().map_err(|_| Unspecified)?; |
37 | 0 | padding_buffer.fill(v); |
38 | | // Possible heap allocation here :( |
39 | 0 | in_out.extend(padding_buffer[0..padding_size].iter()); |
40 | | } |
41 | | } |
42 | 0 | Ok(()) |
43 | 0 | } |
44 | | |
45 | 0 | fn remove_padding(self, block_len: usize, in_out: &mut [u8]) -> Result<&mut [u8], Unspecified> { |
46 | 0 | if in_out.is_empty() || in_out.len() < block_len { |
47 | 0 | return Err(Unspecified); |
48 | 0 | } |
49 | 0 | match self { |
50 | | PaddingStrategy::ISO10126 => { |
51 | 0 | let padding: u8 = in_out[in_out.len() - 1]; |
52 | 0 | if padding == 0 || padding as usize > block_len { |
53 | 0 | return Err(Unspecified); |
54 | 0 | } |
55 | | |
56 | | // ISO 10126 padding is a random padding scheme, so we cannot verify the padding bytes |
57 | 0 | let final_len = in_out.len() - padding as usize; |
58 | 0 | Ok(&mut in_out[0..final_len]) |
59 | | } |
60 | | PaddingStrategy::PKCS7 => { |
61 | 0 | let block_size: u8 = block_len.try_into().map_err(|_| Unspecified)?; |
62 | | |
63 | 0 | let padding: u8 = in_out[in_out.len() - 1]; |
64 | 0 | if padding == 0 || padding > block_size { |
65 | 0 | return Err(Unspecified); |
66 | 0 | } |
67 | | |
68 | 0 | for item in in_out.iter().skip(in_out.len() - padding as usize) { |
69 | 0 | if *item != padding { |
70 | 0 | return Err(Unspecified); |
71 | 0 | } |
72 | | } |
73 | | |
74 | 0 | let final_len = in_out.len() - padding as usize; |
75 | 0 | Ok(&mut in_out[0..final_len]) |
76 | | } |
77 | | } |
78 | 0 | } |
79 | | } |
80 | | |
81 | | /// A cipher encryption key that performs block padding. |
82 | | pub struct PaddedBlockEncryptingKey { |
83 | | algorithm: &'static Algorithm, |
84 | | key: SymmetricCipherKey, |
85 | | mode: OperatingMode, |
86 | | padding: PaddingStrategy, |
87 | | } |
88 | | |
89 | | impl PaddedBlockEncryptingKey { |
90 | | /// Constructs a new `PaddedBlockEncryptingKey` cipher with chaining block cipher (CBC) mode. |
91 | | /// Plaintext data is padded following the PKCS#7 scheme. |
92 | | /// |
93 | | // # FIPS |
94 | | // Use this function with an `UnboundCipherKey` constructed with one of the following algorithms: |
95 | | // * `AES_128` |
96 | | // * `AES_256` |
97 | | // |
98 | | /// # Errors |
99 | | /// * [`Unspecified`]: Returned if there is an error constructing a `PaddedBlockEncryptingKey`. |
100 | 0 | pub fn cbc_pkcs7(key: UnboundCipherKey) -> Result<Self, Unspecified> { |
101 | 0 | Self::new(key, OperatingMode::CBC, PaddingStrategy::PKCS7) |
102 | 0 | } |
103 | | |
104 | | /// Constructs a new `PaddedBlockEncryptingKey` cipher with electronic code book (ECB) mode. |
105 | | /// Plaintext data is padded following the PKCS#7 scheme. |
106 | | /// |
107 | | /// # ☠️ ️️️DANGER ☠️ |
108 | | /// Offered for computability purposes only. This is an extremely dangerous mode, and |
109 | | /// very likely not what you want to use. |
110 | | /// |
111 | | /// # Errors |
112 | | /// * [`Unspecified`]: Returned if there is an error constructing a `PaddedBlockEncryptingKey`. |
113 | 0 | pub fn ecb_pkcs7(key: UnboundCipherKey) -> Result<Self, Unspecified> { |
114 | 0 | Self::new(key, OperatingMode::ECB, PaddingStrategy::PKCS7) |
115 | 0 | } |
116 | | |
117 | | #[allow(clippy::unnecessary_wraps)] |
118 | 0 | fn new( |
119 | 0 | key: UnboundCipherKey, |
120 | 0 | mode: OperatingMode, |
121 | 0 | padding: PaddingStrategy, |
122 | 0 | ) -> Result<PaddedBlockEncryptingKey, Unspecified> { |
123 | 0 | let algorithm = key.algorithm(); |
124 | 0 | let key = key.try_into()?; |
125 | 0 | Ok(Self { |
126 | 0 | algorithm, |
127 | 0 | key, |
128 | 0 | mode, |
129 | 0 | padding, |
130 | 0 | }) |
131 | 0 | } |
132 | | |
133 | | /// Returns the cipher algorithm. |
134 | | #[must_use] |
135 | 0 | pub fn algorithm(&self) -> &Algorithm { |
136 | 0 | self.algorithm |
137 | 0 | } |
138 | | |
139 | | /// Returns the cipher operating mode. |
140 | | #[must_use] |
141 | 0 | pub fn mode(&self) -> OperatingMode { |
142 | 0 | self.mode |
143 | 0 | } |
144 | | |
145 | | /// Pads and encrypts data provided in `in_out` in-place. |
146 | | /// Returns a references to the encrypted data. |
147 | | /// |
148 | | /// # Errors |
149 | | /// * [`Unspecified`]: Returned if encryption fails. |
150 | 0 | pub fn encrypt<InOut>(&self, in_out: &mut InOut) -> Result<DecryptionContext, Unspecified> |
151 | 0 | where |
152 | 0 | InOut: AsMut<[u8]> + for<'a> Extend<&'a u8>, |
153 | | { |
154 | 0 | let context = self.algorithm.new_encryption_context(self.mode)?; |
155 | 0 | self.less_safe_encrypt(in_out, context) |
156 | 0 | } |
157 | | |
158 | | /// Pads and encrypts data provided in `in_out` in-place. |
159 | | /// Returns a references to the encryted data. |
160 | | /// |
161 | | /// # Errors |
162 | | /// * [`Unspecified`]: Returned if encryption fails. |
163 | 0 | pub fn less_safe_encrypt<InOut>( |
164 | 0 | &self, |
165 | 0 | in_out: &mut InOut, |
166 | 0 | context: EncryptionContext, |
167 | 0 | ) -> Result<DecryptionContext, Unspecified> |
168 | 0 | where |
169 | 0 | InOut: AsMut<[u8]> + for<'a> Extend<&'a u8>, |
170 | | { |
171 | 0 | if !self |
172 | 0 | .algorithm() |
173 | 0 | .is_valid_encryption_context(self.mode, &context) |
174 | | { |
175 | 0 | return Err(Unspecified); |
176 | 0 | } |
177 | | |
178 | 0 | self.padding |
179 | 0 | .add_padding(self.algorithm().block_len(), in_out)?; |
180 | 0 | cipher::encrypt( |
181 | 0 | self.algorithm(), |
182 | 0 | &self.key, |
183 | 0 | self.mode, |
184 | 0 | in_out.as_mut(), |
185 | 0 | context, |
186 | | ) |
187 | 0 | } |
188 | | } |
189 | | |
190 | | impl Debug for PaddedBlockEncryptingKey { |
191 | 0 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { |
192 | 0 | f.debug_struct("PaddedBlockEncryptingKey") |
193 | 0 | .field("algorithm", &self.algorithm) |
194 | 0 | .field("mode", &self.mode) |
195 | 0 | .field("padding", &self.padding) |
196 | 0 | .finish_non_exhaustive() |
197 | 0 | } |
198 | | } |
199 | | |
200 | | /// A cipher decryption key that performs block padding. |
201 | | pub struct PaddedBlockDecryptingKey { |
202 | | algorithm: &'static Algorithm, |
203 | | key: SymmetricCipherKey, |
204 | | mode: OperatingMode, |
205 | | padding: PaddingStrategy, |
206 | | } |
207 | | |
208 | | impl PaddedBlockDecryptingKey { |
209 | | /// Constructs a new `PaddedBlockDecryptingKey` cipher with chaining block cipher (CBC) mode. |
210 | | /// Decrypted data is unpadded following the PKCS#7 scheme. |
211 | | /// |
212 | | // # FIPS |
213 | | // Use this function with an `UnboundCipherKey` constructed with one of the following algorithms: |
214 | | // * `AES_128` |
215 | | // * `AES_256` |
216 | | // |
217 | | /// # Errors |
218 | | /// * [`Unspecified`]: Returned if there is an error constructing the `PaddedBlockDecryptingKey`. |
219 | 0 | pub fn cbc_pkcs7(key: UnboundCipherKey) -> Result<Self, Unspecified> { |
220 | 0 | Self::new(key, OperatingMode::CBC, PaddingStrategy::PKCS7) |
221 | 0 | } |
222 | | |
223 | | /// Constructs a new `PaddedBlockDecryptingKey` cipher with chaining block cipher (CBC) mode. |
224 | | /// Decrypted data is unpadded following the ISO 10126 scheme |
225 | | /// (compatible with PKCS#7 and ANSI X.923). |
226 | | /// |
227 | | /// Offered for computability purposes only. |
228 | | /// |
229 | | // # FIPS |
230 | | // Use this function with an `UnboundCipherKey` constructed with one of the following algorithms: |
231 | | // * `AES_128` |
232 | | // * `AES_256` |
233 | | // |
234 | | /// # Errors |
235 | | /// * [`Unspecified`]: Returned if there is an error constructing the `PaddedBlockDecryptingKey`. |
236 | 0 | pub fn cbc_iso10126(key: UnboundCipherKey) -> Result<Self, Unspecified> { |
237 | 0 | Self::new(key, OperatingMode::CBC, PaddingStrategy::ISO10126) |
238 | 0 | } |
239 | | |
240 | | /// Constructs a new `PaddedBlockDecryptingKey` cipher with electronic code book (ECB) mode. |
241 | | /// Decrypted data is unpadded following the PKCS#7 scheme. |
242 | | /// |
243 | | /// # ☠️ ️️️DANGER ☠️ |
244 | | /// Offered for computability purposes only. This is an extremely dangerous mode, and |
245 | | /// very likely not what you want to use. |
246 | | /// |
247 | | // # FIPS |
248 | | // Use this function with an `UnboundCipherKey` constructed with one of the following algorithms: |
249 | | // * `AES_128` |
250 | | // * `AES_256` |
251 | | // |
252 | | /// # Errors |
253 | | /// * [`Unspecified`]: Returned if there is an error constructing the `PaddedBlockDecryptingKey`. |
254 | 0 | pub fn ecb_pkcs7(key: UnboundCipherKey) -> Result<Self, Unspecified> { |
255 | 0 | Self::new(key, OperatingMode::ECB, PaddingStrategy::PKCS7) |
256 | 0 | } |
257 | | |
258 | | #[allow(clippy::unnecessary_wraps)] |
259 | 0 | fn new( |
260 | 0 | key: UnboundCipherKey, |
261 | 0 | mode: OperatingMode, |
262 | 0 | padding: PaddingStrategy, |
263 | 0 | ) -> Result<PaddedBlockDecryptingKey, Unspecified> { |
264 | 0 | let algorithm = key.algorithm(); |
265 | 0 | let key = key.try_into()?; |
266 | 0 | Ok(PaddedBlockDecryptingKey { |
267 | 0 | algorithm, |
268 | 0 | key, |
269 | 0 | mode, |
270 | 0 | padding, |
271 | 0 | }) |
272 | 0 | } |
273 | | |
274 | | /// Returns the cipher algorithm. |
275 | | #[must_use] |
276 | 0 | pub fn algorithm(&self) -> &Algorithm { |
277 | 0 | self.algorithm |
278 | 0 | } |
279 | | |
280 | | /// Returns the cipher operating mode. |
281 | | #[must_use] |
282 | 0 | pub fn mode(&self) -> OperatingMode { |
283 | 0 | self.mode |
284 | 0 | } |
285 | | |
286 | | /// Decrypts and unpads data provided in `in_out` in-place. |
287 | | /// Returns a references to the decrypted data. |
288 | | /// |
289 | | /// # Errors |
290 | | /// * [`Unspecified`]: Returned if decryption fails. |
291 | 0 | pub fn decrypt<'in_out>( |
292 | 0 | &self, |
293 | 0 | in_out: &'in_out mut [u8], |
294 | 0 | context: DecryptionContext, |
295 | 0 | ) -> Result<&'in_out mut [u8], Unspecified> { |
296 | 0 | if !self |
297 | 0 | .algorithm() |
298 | 0 | .is_valid_decryption_context(self.mode, &context) |
299 | | { |
300 | 0 | return Err(Unspecified); |
301 | 0 | } |
302 | | |
303 | 0 | let block_len = self.algorithm().block_len(); |
304 | 0 | let padding = self.padding; |
305 | 0 | let mut in_out = cipher::decrypt(self.algorithm, &self.key, self.mode, in_out, context)?; |
306 | 0 | in_out = padding.remove_padding(block_len, in_out)?; |
307 | 0 | Ok(in_out) |
308 | 0 | } |
309 | | } |
310 | | |
311 | | impl Debug for PaddedBlockDecryptingKey { |
312 | 0 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { |
313 | 0 | f.debug_struct("PaddedBlockDecryptingKey") |
314 | 0 | .field("algorithm", &self.algorithm) |
315 | 0 | .field("mode", &self.mode) |
316 | 0 | .field("padding", &self.padding) |
317 | 0 | .finish_non_exhaustive() |
318 | 0 | } |
319 | | } |
320 | | |
321 | | #[cfg(test)] |
322 | | mod tests { |
323 | | use crate::cipher::padded::PaddingStrategy; |
324 | | use crate::cipher::{ |
325 | | Algorithm, EncryptionContext, OperatingMode, PaddedBlockDecryptingKey, |
326 | | PaddedBlockEncryptingKey, UnboundCipherKey, AES_128, AES_256, |
327 | | }; |
328 | | use crate::iv::FixedLength; |
329 | | use crate::test::from_hex; |
330 | | |
331 | | fn helper_test_padded_cipher_n_bytes( |
332 | | key: &[u8], |
333 | | alg: &'static Algorithm, |
334 | | mode: OperatingMode, |
335 | | padding: PaddingStrategy, |
336 | | n: usize, |
337 | | ) { |
338 | | let mut input: Vec<u8> = Vec::with_capacity(n); |
339 | | for i in 0..n { |
340 | | let byte: u8 = i.try_into().unwrap(); |
341 | | input.push(byte); |
342 | | } |
343 | | |
344 | | let cipher_key = UnboundCipherKey::new(alg, key).unwrap(); |
345 | | let encrypting_key = PaddedBlockEncryptingKey::new(cipher_key, mode, padding).unwrap(); |
346 | | |
347 | | let mut in_out = input.clone(); |
348 | | let decrypt_iv = encrypting_key.encrypt(&mut in_out).unwrap(); |
349 | | |
350 | | if n > 5 { |
351 | | // There's no more than a 1 in 2^48 chance that this will fail randomly |
352 | | assert_ne!(input.as_slice(), in_out); |
353 | | } |
354 | | |
355 | | let cipher_key2 = UnboundCipherKey::new(alg, key).unwrap(); |
356 | | let decrypting_key = PaddedBlockDecryptingKey::new(cipher_key2, mode, padding).unwrap(); |
357 | | |
358 | | let plaintext = decrypting_key.decrypt(&mut in_out, decrypt_iv).unwrap(); |
359 | | assert_eq!(input.as_slice(), plaintext); |
360 | | } |
361 | | |
362 | | #[test] |
363 | | fn test_unpad_iso10126() { |
364 | | let mut input = from_hex("01020304050607fedcba9805").unwrap(); |
365 | | let padding = PaddingStrategy::ISO10126; |
366 | | let block_len = 8; |
367 | | |
368 | | let unpadded = padding.remove_padding(block_len, &mut input).unwrap(); |
369 | | assert_eq!(unpadded, &mut [1, 2, 3, 4, 5, 6, 7]); |
370 | | } |
371 | | |
372 | | #[test] |
373 | | fn test_aes_128_cbc() { |
374 | | let key = from_hex("000102030405060708090a0b0c0d0e0f").unwrap(); |
375 | | for i in 0..=50 { |
376 | | helper_test_padded_cipher_n_bytes( |
377 | | key.as_slice(), |
378 | | &AES_128, |
379 | | OperatingMode::CBC, |
380 | | PaddingStrategy::PKCS7, |
381 | | i, |
382 | | ); |
383 | | } |
384 | | } |
385 | | |
386 | | #[test] |
387 | | fn test_aes_256_cbc() { |
388 | | let key = |
389 | | from_hex("000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f").unwrap(); |
390 | | for i in 0..=50 { |
391 | | helper_test_padded_cipher_n_bytes( |
392 | | key.as_slice(), |
393 | | &AES_256, |
394 | | OperatingMode::CBC, |
395 | | PaddingStrategy::PKCS7, |
396 | | i, |
397 | | ); |
398 | | } |
399 | | } |
400 | | |
401 | | macro_rules! padded_cipher_kat { |
402 | | ($name:ident, $alg:expr, $mode:expr, $padding:expr, $key:literal, $iv: literal, $plaintext:literal, $ciphertext:literal) => { |
403 | | #[test] |
404 | | fn $name() { |
405 | | let key = from_hex($key).unwrap(); |
406 | | let input = from_hex($plaintext).unwrap(); |
407 | | let expected_ciphertext = from_hex($ciphertext).unwrap(); |
408 | | let mut iv = from_hex($iv).unwrap(); |
409 | | let iv = { |
410 | | let slice = iv.as_mut_slice(); |
411 | | let mut iv = [0u8; $iv.len() / 2]; |
412 | | { |
413 | | let x = iv.as_mut_slice(); |
414 | | x.copy_from_slice(slice); |
415 | | } |
416 | | iv |
417 | | }; |
418 | | |
419 | | let ec = EncryptionContext::Iv128(FixedLength::from(iv)); |
420 | | |
421 | | let alg = $alg; |
422 | | |
423 | | let unbound_key = UnboundCipherKey::new(alg, &key).unwrap(); |
424 | | |
425 | | let encrypting_key = |
426 | | PaddedBlockEncryptingKey::new(unbound_key, $mode, $padding).unwrap(); |
427 | | |
428 | | let mut in_out = input.clone(); |
429 | | |
430 | | let context = encrypting_key.less_safe_encrypt(&mut in_out, ec).unwrap(); |
431 | | |
432 | | if ($padding == PaddingStrategy::ISO10126) { |
433 | | // This padding scheme is technically non-deterministic in nature if the padding is more then one |
434 | | // byte. So just validate the input length of in_out is no longer the plaintext. |
435 | | assert_ne!(input, in_out[..input.len()]); |
436 | | } else { |
437 | | assert_eq!(expected_ciphertext, in_out); |
438 | | } |
439 | | |
440 | | let unbound_key2 = UnboundCipherKey::new(alg, &key).unwrap(); |
441 | | let decrypting_key = |
442 | | PaddedBlockDecryptingKey::new(unbound_key2, $mode, $padding).unwrap(); |
443 | | |
444 | | let plaintext = decrypting_key.decrypt(&mut in_out, context).unwrap(); |
445 | | assert_eq!(input.as_slice(), plaintext); |
446 | | } |
447 | | }; |
448 | | } |
449 | | |
450 | | padded_cipher_kat!( |
451 | | test_iv_aes_128_cbc_16_bytes, |
452 | | &AES_128, |
453 | | OperatingMode::CBC, |
454 | | PaddingStrategy::PKCS7, |
455 | | "000102030405060708090a0b0c0d0e0f", |
456 | | "00000000000000000000000000000000", |
457 | | "00112233445566778899aabbccddeeff", |
458 | | "69c4e0d86a7b0430d8cdb78070b4c55a9e978e6d16b086570ef794ef97984232" |
459 | | ); |
460 | | |
461 | | padded_cipher_kat!( |
462 | | test_iv_aes_256_cbc_15_bytes, |
463 | | &AES_256, |
464 | | OperatingMode::CBC, |
465 | | PaddingStrategy::PKCS7, |
466 | | "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", |
467 | | "00000000000000000000000000000000", |
468 | | "00112233445566778899aabbccddee", |
469 | | "2ddfb635a651a43f582997966840ca0c" |
470 | | ); |
471 | | |
472 | | padded_cipher_kat!( |
473 | | test_openssl_aes_128_cbc_15_bytes, |
474 | | &AES_128, |
475 | | OperatingMode::CBC, |
476 | | PaddingStrategy::PKCS7, |
477 | | "053304bb3899e1d99db9d29343ea782d", |
478 | | "b5313560244a4822c46c2a0c9d0cf7fd", |
479 | | "a3e4c990356c01f320043c3d8d6f43", |
480 | | "ad96993f248bd6a29760ec7ccda95ee1" |
481 | | ); |
482 | | |
483 | | padded_cipher_kat!( |
484 | | test_openssl_aes_128_cbc_iso10126_15_bytes, |
485 | | &AES_128, |
486 | | OperatingMode::CBC, |
487 | | PaddingStrategy::ISO10126, |
488 | | "053304bb3899e1d99db9d29343ea782d", |
489 | | "b5313560244a4822c46c2a0c9d0cf7fd", |
490 | | "a3e4c990356c01f320043c3d8d6f43", |
491 | | "ad96993f248bd6a29760ec7ccda95ee1" |
492 | | ); |
493 | | |
494 | | padded_cipher_kat!( |
495 | | test_openssl_aes_128_cbc_iso10126_16_bytes, |
496 | | &AES_128, |
497 | | OperatingMode::CBC, |
498 | | PaddingStrategy::ISO10126, |
499 | | "053304bb3899e1d99db9d29343ea782d", |
500 | | "b83452fc9c80215a6ecdc505b5154c90", |
501 | | "736e65616b7920726163636f6f6e7321", |
502 | | "44563399c6bb2133e013161dc5bd4fa8ce83ef997ddb04bbbbe3632b68e9cde0" |
503 | | ); |
504 | | |
505 | | padded_cipher_kat!( |
506 | | test_openssl_aes_128_cbc_16_bytes, |
507 | | &AES_128, |
508 | | OperatingMode::CBC, |
509 | | PaddingStrategy::PKCS7, |
510 | | "95af71f1c63e4a1d0b0b1a27fb978283", |
511 | | "89e40797dca70197ff87d3dbb0ef2802", |
512 | | "aece7b5e3c3df1ffc9802d2dfe296dc7", |
513 | | "301b5dab49fb11e919d0d39970d06739301919743304f23f3cbc67d28564b25b" |
514 | | ); |
515 | | |
516 | | padded_cipher_kat!( |
517 | | test_openssl_aes_256_cbc_15_bytes, |
518 | | &AES_256, |
519 | | OperatingMode::CBC, |
520 | | PaddingStrategy::PKCS7, |
521 | | "d369e03e9752784917cc7bac1db7399598d9555e691861d9dd7b3292a693ef57", |
522 | | "1399bb66b2f6ad99a7f064140eaaa885", |
523 | | "7385f5784b85bf0a97768ddd896d6d", |
524 | | "4351082bac9b4593ae8848cc9dfb5a01" |
525 | | ); |
526 | | |
527 | | padded_cipher_kat!( |
528 | | test_openssl_aes_256_cbc_16_bytes, |
529 | | &AES_256, |
530 | | OperatingMode::CBC, |
531 | | PaddingStrategy::PKCS7, |
532 | | "d4a8206dcae01242f9db79a4ecfe277d0f7bb8ccbafd8f9809adb39f35aa9b41", |
533 | | "24f6076548fb9d93c8f7ed9f6e661ef9", |
534 | | "a39c1fdf77ea3e1f18178c0ec237c70a", |
535 | | "f1af484830a149ee0387b854d65fe87ca0e62efc1c8e6909d4b9ab8666470453" |
536 | | ); |
537 | | } |