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