psa_crypto/operations/aead.rs
1// Copyright 2020 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3
4//! # Authenticated Encryption with Associated Data (AEAD) operations
5//!
6//! See the PSA Crypto API for the format of the different parameters used in this module.
7
8use crate::initialized;
9use crate::types::algorithm::Aead;
10use crate::types::key::Id;
11use crate::types::status::{Result, Status};
12
13/// Process an authenticated encryption operation.
14/// # Example
15///
16/// ```
17/// use psa_crypto::types::algorithm::{Aead, AeadWithDefaultLengthTag};
18/// use psa_crypto::types::key::{Attributes, Type, Lifetime, Policy, UsageFlags};
19/// use psa_crypto::operations::{key_management, aead};
20/// # const KEY_DATA: [u8; 16] = [0x41, 0x89, 0x35, 0x1B, 0x5C, 0xAE, 0xA3, 0x75, 0xA0, 0x29, 0x9E, 0x81, 0xC6, 0x21, 0xBF, 0x43];
21/// # const NONCE: [u8; 13] = [0x48, 0xc0, 0x90, 0x69, 0x30, 0x56, 0x1e, 0x0a, 0xb0, 0xef, 0x4c, 0xd9, 0x72];
22/// # const ADDITIONAL_DATA: [u8; 32] = [0x40, 0xa2, 0x7c, 0x1d, 0x1e, 0x23, 0xea, 0x3d, 0xbe, 0x80, 0x56, 0xb2,
23/// # 0x77, 0x48, 0x61, 0xa4, 0xa2, 0x01, 0xcc, 0xe4, 0x9f, 0x19, 0x99, 0x7d, 0x19, 0x20, 0x6d, 0x8c, 0x8a, 0x34, 0x39, 0x51];
24/// # const INPUT_DATA: [u8; 24] = [0x45, 0x35, 0xd1, 0x2b, 0x43, 0x77, 0x92, 0x8a, 0x7c, 0x0a, 0x61, 0xc9, 0xf8, 0x25, 0xa4, 0x86,
25/// # 0x71, 0xea, 0x05, 0x91, 0x07, 0x48, 0xc8, 0xef];
26/// let alg = Aead::AeadWithDefaultLengthTag(AeadWithDefaultLengthTag::Ccm);
27/// let mut usage_flags: UsageFlags = Default::default();
28/// usage_flags.set_encrypt();
29/// let attributes = Attributes {
30/// key_type: Type::Aes,
31/// bits: 0,
32/// lifetime: Lifetime::Volatile,
33/// policy: Policy {
34/// usage_flags,
35/// permitted_algorithms: alg.into(),
36/// },
37/// };
38/// psa_crypto::init().unwrap();
39/// let my_key = key_management::import(attributes, None, &KEY_DATA).unwrap();
40/// let output_buffer_size = attributes.aead_encrypt_output_size(alg.into(), INPUT_DATA.len()).unwrap();
41/// let mut output_buffer = vec![0; output_buffer_size];
42/// let length = aead::encrypt(my_key, alg, &NONCE, &ADDITIONAL_DATA, &INPUT_DATA, &mut output_buffer).unwrap();
43/// output_buffer.resize(length, 0);
44/// ```
45pub fn encrypt(
46 key_id: Id,
47 aead_alg: Aead,
48 nonce: &[u8],
49 additional_data: &[u8],
50 plaintext: &[u8],
51 ciphertext: &mut [u8],
52) -> Result<usize> {
53 initialized()?;
54
55 let mut ciphertext_size = 0;
56 Status::from(unsafe {
57 psa_crypto_sys::psa_aead_encrypt(
58 key_id.0,
59 aead_alg.into(),
60 nonce.as_ptr(),
61 nonce.len(),
62 additional_data.as_ptr(),
63 additional_data.len(),
64 plaintext.as_ptr(),
65 plaintext.len(),
66 ciphertext.as_mut_ptr(),
67 ciphertext.len(),
68 &mut ciphertext_size,
69 )
70 })
71 .to_result()?;
72 Ok(ciphertext_size)
73}
74
75/// Process an authenticated decryption operation.
76/// # Example
77///
78/// ```
79/// use psa_crypto::types::algorithm::{Aead, AeadWithDefaultLengthTag};
80/// use psa_crypto::types::key::{Attributes, Type, Lifetime, Policy, UsageFlags};
81/// use psa_crypto::operations::{key_management, aead};
82/// # const KEY_DATA: [u8; 16] = [0x41, 0x89, 0x35, 0x1B, 0x5C, 0xAE, 0xA3, 0x75, 0xA0, 0x29, 0x9E, 0x81, 0xC6, 0x21, 0xBF, 0x43];
83/// # const NONCE: [u8; 13] = [0x48, 0xc0, 0x90, 0x69, 0x30, 0x56, 0x1e, 0x0a, 0xb0, 0xef, 0x4c, 0xd9, 0x72];
84/// # const ADDITIONAL_DATA: [u8; 32] = [0x40, 0xa2, 0x7c, 0x1d, 0x1e, 0x23, 0xea, 0x3d, 0xbe, 0x80, 0x56, 0xb2,
85/// # 0x77, 0x48, 0x61, 0xa4, 0xa2, 0x01, 0xcc, 0xe4, 0x9f, 0x19, 0x99, 0x7d, 0x19, 0x20, 0x6d, 0x8c, 0x8a, 0x34, 0x39, 0x51];
86/// # const INPUT_DATA: [u8; 40] = [0x26, 0xc5, 0x69, 0x61, 0xc0, 0x35, 0xa7, 0xe4, 0x52, 0xcc, 0xe6, 0x1b, 0xc6, 0xee, 0x22, 0x0d,
87/// # 0x77, 0xb3, 0xf9, 0x4d, 0x18, 0xfd, 0x10, 0xb6, 0xd8, 0x0e, 0x8b, 0xf8, 0x0f, 0x4a, 0x46, 0xca, 0xb0, 0x6d, 0x43, 0x13, 0xf0, 0xdb, 0x9b, 0xe9];
88/// let alg = Aead::AeadWithDefaultLengthTag(AeadWithDefaultLengthTag::Ccm);
89/// let mut usage_flags: UsageFlags = Default::default();
90/// usage_flags.set_decrypt();
91/// let attributes = Attributes {
92/// key_type: Type::Aes,
93/// bits: 0,
94/// lifetime: Lifetime::Volatile,
95/// policy: Policy {
96/// usage_flags,
97/// permitted_algorithms: alg.into(),
98/// },
99/// };
100/// psa_crypto::init().unwrap();
101/// let my_key = key_management::import(attributes, None, &KEY_DATA).unwrap();
102/// let output_buffer_size = attributes.aead_decrypt_output_size(alg.into(), INPUT_DATA.len()).unwrap();
103/// let mut output_buffer = vec![0; output_buffer_size];
104/// let length = aead::decrypt(my_key, alg, &NONCE, &ADDITIONAL_DATA, &INPUT_DATA, &mut output_buffer).unwrap();
105/// output_buffer.resize(length, 0);
106/// ```
107pub fn decrypt(
108 key_id: Id,
109 aead_alg: Aead,
110 nonce: &[u8],
111 additional_data: &[u8],
112 ciphertext: &[u8],
113 plaintext: &mut [u8],
114) -> Result<usize> {
115 initialized()?;
116
117 let mut plaintext_size = 0;
118
119 Status::from(unsafe {
120 psa_crypto_sys::psa_aead_decrypt(
121 key_id.0,
122 aead_alg.into(),
123 nonce.as_ptr(),
124 nonce.len(),
125 additional_data.as_ptr(),
126 additional_data.len(),
127 ciphertext.as_ptr(),
128 ciphertext.len(),
129 plaintext.as_mut_ptr(),
130 plaintext.len(),
131 &mut plaintext_size,
132 )
133 })
134 .to_result()?;
135 Ok(plaintext_size)
136}