blob: f82028582a51c9f048ab2bd8970949610f1c3c69 [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 Wang0271ee02023-11-15 15:03:42 +000018use crate::sha::SHA256_DIGEST_LENGTH;
Alice Wang47287e72023-09-29 13:14:33 +000019use crate::util::to_call_failed_error;
20use bssl_avf_error::{ApiName, Result};
Maurice Lam0322b8c2023-12-18 22:13:48 +000021use bssl_sys::HMAC;
Alice Wang709cce92023-09-26 10:30:21 +000022
23/// Computes the HMAC using SHA-256 for the given `data` with the given `key`.
Alice Wang0271ee02023-11-15 15:03:42 +000024pub fn hmac_sha256(key: &[u8], data: &[u8]) -> Result<[u8; SHA256_DIGEST_LENGTH]> {
25 hmac::<SHA256_DIGEST_LENGTH>(key, data, Digester::sha256())
Alice Wang709cce92023-09-26 10:30:21 +000026}
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 {
Alice Wang47287e72023-09-29 13:14:33 +000056 Err(to_call_failed_error(ApiName::HMAC))
Alice Wang709cce92023-09-26 10:30:21 +000057 }
58}