Skip to main content

wasefire/crypto/
ccm.rs

1// Copyright 2022 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Provides AES-CCM as defined by Bluetooth.
16
17use alloc::vec;
18use alloc::vec::Vec;
19
20use wasefire_applet_api::crypto::ccm as api;
21
22use crate::{Error, convert_bool, convert_unit};
23
24/// Whether AES-CCM is supported.
25pub fn is_supported() -> bool {
26    convert_bool(unsafe { api::is_supported() }).unwrap_or(false)
27}
28
29/// Returns the ciphertext given a cleartext, a key, and a nonce.
30pub fn encrypt(key: &[u8; 16], nonce: &[u8; 8], clear: &[u8]) -> Result<Vec<u8>, Error> {
31    let len = clear.len();
32    let mut cipher = vec![0; len + 4];
33    let params = api::encrypt::Params {
34        key: key.as_ptr(),
35        iv: nonce.as_ptr(),
36        len,
37        clear: clear.as_ptr(),
38        cipher: cipher.as_mut_ptr(),
39    };
40    convert_unit(unsafe { api::encrypt(params) })?;
41    Ok(cipher)
42}
43
44/// Returns the cleartext given a ciphertext, a key, and a nonce.
45pub fn decrypt(key: &[u8; 16], nonce: &[u8; 8], cipher: &[u8]) -> Result<Vec<u8>, Error> {
46    let len = cipher.len().checked_sub(4).ok_or(Error::user(0))?;
47    let mut clear = vec![0; len];
48    let params = api::decrypt::Params {
49        key: key.as_ptr(),
50        iv: nonce.as_ptr(),
51        len,
52        cipher: cipher.as_ptr(),
53        clear: clear.as_mut_ptr(),
54    };
55    convert_unit(unsafe { api::decrypt(params) })?;
56    Ok(clear)
57}