blob: 1e093155a83650097ff70130a9e5db1f399ecd44 [file] [log] [blame]
Alice Wang709cce92023-09-26 10:30:21 +00001// Copyright 2023, The Android Open Source Project
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//! Wrappers of the HMAC functions in BoringSSL hmac.h.
16
17use crate::digest::Digester;
18use bssl_avf_error::{ApiName, Error, Result};
19use bssl_ffi::{HMAC, SHA256_DIGEST_LENGTH};
20
21const SHA256_LEN: usize = SHA256_DIGEST_LENGTH as usize;
22
23/// Computes the HMAC using SHA-256 for the given `data` with the given `key`.
24pub fn hmac_sha256(key: &[u8], data: &[u8]) -> Result<[u8; SHA256_LEN]> {
25 hmac::<SHA256_LEN>(key, data, Digester::sha256())
26}
27
28/// Computes the HMAC for the given `data` with the given `key` and `digester`.
29///
30/// The output size `HASH_LEN` should correspond to the length of the hash function's
31/// digest size in bytes.
32fn hmac<const HASH_LEN: usize>(
33 key: &[u8],
34 data: &[u8],
35 digester: Digester,
36) -> Result<[u8; HASH_LEN]> {
37 assert_eq!(digester.size(), HASH_LEN);
38
39 let mut out = [0u8; HASH_LEN];
40 let mut out_len = 0;
41 // SAFETY: Only reads from/writes to the provided slices and the digester was non-null.
42 let ret = unsafe {
43 HMAC(
44 digester.0,
45 key.as_ptr() as *const _,
46 key.len(),
47 data.as_ptr(),
48 data.len(),
49 out.as_mut_ptr(),
50 &mut out_len,
51 )
52 };
53 if !ret.is_null() && out_len == (out.len() as u32) {
54 Ok(out)
55 } else {
56 Err(Error::CallFailed(ApiName::HMAC))
57 }
58}