17689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong/* 27689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong * Copyright 2015 The Android Open Source Project 37689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong * 47689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong * Licensed under the Apache License, Version 2.0 (the "License"); 57689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong * you may not use this file except in compliance with the License. 67689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong * You may obtain a copy of the License at 77689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong * 87689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong * http://www.apache.org/licenses/LICENSE-2.0 97689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong * 107689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong * Unless required by applicable law or agreed to in writing, software 117689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong * distributed under the License is distributed on an "AS IS" BASIS, 127689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong * See the License for the specific language governing permissions and 147689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong * limitations under the License. 157689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong */ 167689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong 177689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong#include "hmac.h" 187689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong 197689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong#include <assert.h> 200f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden 217689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong#include <openssl/evp.h> 227689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong#include <openssl/hmac.h> 230f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden#include <openssl/mem.h> 247689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong#include <openssl/sha.h> 257689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong 260f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden#include <keymaster/android_keymaster_utils.h> 27c3326552d973ce34f0f3138333a05a4a1865a699Adam Langley 287689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duongnamespace keymaster { 297689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong 307689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duongsize_t HmacSha256::DigestLength() const { 317689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong return SHA256_DIGEST_LENGTH; 327689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong} 337689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong 3460eebdc0b92724cd550aeba92d124cd50c4db5aeThai Duongbool HmacSha256::Init(const Buffer& key) { 3560eebdc0b92724cd550aeba92d124cd50c4db5aeThai Duong return Init(key.peek_read(), key.available_read()); 3660eebdc0b92724cd550aeba92d124cd50c4db5aeThai Duong} 3760eebdc0b92724cd550aeba92d124cd50c4db5aeThai Duong 387689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duongbool HmacSha256::Init(const uint8_t* key, size_t key_len) { 397689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong if (!key) 407689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong return false; 417689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong 4260eebdc0b92724cd550aeba92d124cd50c4db5aeThai Duong key_len_ = key_len; 430f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden key_.reset(dup_buffer(key, key_len)); 4460eebdc0b92724cd550aeba92d124cd50c4db5aeThai Duong if (!key_.get()) { 4560eebdc0b92724cd550aeba92d124cd50c4db5aeThai Duong return false; 4660eebdc0b92724cd550aeba92d124cd50c4db5aeThai Duong } 477689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong return true; 487689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong} 497689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong 507689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duongbool HmacSha256::Sign(const Buffer& data, uint8_t* out_digest, size_t digest_len) const { 517689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong return Sign(data.peek_read(), data.available_read(), out_digest, digest_len); 527689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong} 537689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong 547689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duongbool HmacSha256::Sign(const uint8_t* data, size_t data_len, uint8_t* out_digest, 5560eebdc0b92724cd550aeba92d124cd50c4db5aeThai Duong size_t digest_len) const { 567689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong assert(digest_len); 577689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong 587689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong uint8_t tmp[SHA256_DIGEST_LENGTH]; 597689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong uint8_t* digest = tmp; 607689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong if (digest_len >= SHA256_DIGEST_LENGTH) 617689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong digest = out_digest; 627689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong 6360eebdc0b92724cd550aeba92d124cd50c4db5aeThai Duong if (nullptr == ::HMAC(EVP_sha256(), key_.get(), key_len_, data, data_len, digest, nullptr)) { 647689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong return false; 657689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong } 667689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong if (digest_len < SHA256_DIGEST_LENGTH) 677689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong memcpy(out_digest, tmp, digest_len); 687689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong 697689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong return true; 707689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong} 717689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong 727689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duongbool HmacSha256::Verify(const Buffer& data, const Buffer& digest) const { 737689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong return Verify(data.peek_read(), data.available_read(), digest.peek_read(), 747689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong digest.available_read()); 757689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong} 767689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong 777689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duongbool HmacSha256::Verify(const uint8_t* data, size_t data_len, const uint8_t* digest, 7860eebdc0b92724cd550aeba92d124cd50c4db5aeThai Duong size_t digest_len) const { 797689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong if (digest_len != SHA256_DIGEST_LENGTH) 807689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong return false; 817689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong 827689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong uint8_t computed_digest[SHA256_DIGEST_LENGTH]; 837689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong if (!Sign(data, data_len, computed_digest, sizeof(computed_digest))) 847689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong return false; 857689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong 867689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong return 0 == CRYPTO_memcmp(digest, computed_digest, SHA256_DIGEST_LENGTH); 877689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong} 887689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong 897689ed6e95e5cb712c4983cb30ad383520cfaa33Thai Duong} // namespace keymaster 90