1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//! Decrypt data which was encrypted (using AES-CCM) under a wrap key
//!
//! https://developers.yubico.com/YubiHSM2/Commands/Unwrap_Data.html

use super::{Command, Response};
use {Adapter, CommandType, ObjectId, Session, SessionError, WrapMessage, WrapNonce};

/// Decrypt data which was encrypted (using AES-CCM) under a wrap key
pub fn unwrap_data<A, M>(
    session: &mut Session<A>,
    wrap_key_id: ObjectId,
    wrap_message: M,
) -> Result<Vec<u8>, SessionError>
where
    A: Adapter,
    M: Into<WrapMessage>,
{
    let WrapMessage { nonce, ciphertext } = wrap_message.into();

    session
        .send_command(UnwrapDataCommand {
            wrap_key_id,
            nonce,
            ciphertext,
        }).map(|response| response.0)
}

/// Request parameters for `commands::unwrap_data`
#[derive(Serialize, Deserialize, Debug)]
pub(crate) struct UnwrapDataCommand {
    /// ID of the wrap key to decrypt the object with
    pub wrap_key_id: ObjectId,

    /// Nonce used to encrypt the wrapped data
    pub nonce: WrapNonce,

    /// Ciphertext of the encrypted data (including MAC)
    pub ciphertext: Vec<u8>,
}

impl Command for UnwrapDataCommand {
    type ResponseType = UnwrapDataResponse;
}

/// Response from `commands::unwrap_data` containing decrypted plaintext
#[derive(Serialize, Deserialize, Debug)]
pub(crate) struct UnwrapDataResponse(pub(crate) Vec<u8>);

impl Response for UnwrapDataResponse {
    const COMMAND_TYPE: CommandType = CommandType::UnwrapData;
}