1 // 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
17 use crate::digest::Digester;
18 use crate::sha::SHA256_DIGEST_LENGTH;
19 use crate::util::to_call_failed_error;
20 use bssl_avf_error::{ApiName, Result};
21 use bssl_sys::HMAC;
22
23 /// Computes the HMAC using SHA-256 for the given `data` with the given `key`.
hmac_sha256(key: &[u8], data: &[u8]) -> Result<[u8; SHA256_DIGEST_LENGTH]>24 pub fn hmac_sha256(key: &[u8], data: &[u8]) -> Result<[u8; SHA256_DIGEST_LENGTH]> {
25 hmac::<SHA256_DIGEST_LENGTH>(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.
hmac<const HASH_LEN: usize>( key: &[u8], data: &[u8], digester: Digester, ) -> Result<[u8; HASH_LEN]>32 fn 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(to_call_failed_error(ApiName::HMAC))
57 }
58 }
59