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}