Home | History | Annotate | Download | only in keymaster
      1 /*
      2  * Copyright 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "hmac.h"
     18 
     19 #include <assert.h>
     20 
     21 #include <openssl/evp.h>
     22 #include <openssl/hmac.h>
     23 #include <openssl/mem.h>
     24 #include <openssl/sha.h>
     25 
     26 #include <keymaster/android_keymaster_utils.h>
     27 
     28 namespace keymaster {
     29 
     30 size_t HmacSha256::DigestLength() const {
     31     return SHA256_DIGEST_LENGTH;
     32 }
     33 
     34 bool HmacSha256::Init(const Buffer& key) {
     35     return Init(key.peek_read(), key.available_read());
     36 }
     37 
     38 bool HmacSha256::Init(const uint8_t* key, size_t key_len) {
     39     if (!key)
     40         return false;
     41 
     42     key_len_ = key_len;
     43     key_.reset(dup_buffer(key, key_len));
     44     if (!key_.get()) {
     45         return false;
     46     }
     47     return true;
     48 }
     49 
     50 bool HmacSha256::Sign(const Buffer& data, uint8_t* out_digest, size_t digest_len) const {
     51     return Sign(data.peek_read(), data.available_read(), out_digest, digest_len);
     52 }
     53 
     54 bool HmacSha256::Sign(const uint8_t* data, size_t data_len, uint8_t* out_digest,
     55                       size_t digest_len) const {
     56     assert(digest_len);
     57 
     58     uint8_t tmp[SHA256_DIGEST_LENGTH];
     59     uint8_t* digest = tmp;
     60     if (digest_len >= SHA256_DIGEST_LENGTH)
     61         digest = out_digest;
     62 
     63     if (nullptr == ::HMAC(EVP_sha256(), key_.get(), key_len_, data, data_len, digest, nullptr)) {
     64         return false;
     65     }
     66     if (digest_len < SHA256_DIGEST_LENGTH)
     67         memcpy(out_digest, tmp, digest_len);
     68 
     69     return true;
     70 }
     71 
     72 bool HmacSha256::Verify(const Buffer& data, const Buffer& digest) const {
     73     return Verify(data.peek_read(), data.available_read(), digest.peek_read(),
     74                   digest.available_read());
     75 }
     76 
     77 bool HmacSha256::Verify(const uint8_t* data, size_t data_len, const uint8_t* digest,
     78                         size_t digest_len) const {
     79     if (digest_len != SHA256_DIGEST_LENGTH)
     80         return false;
     81 
     82     uint8_t computed_digest[SHA256_DIGEST_LENGTH];
     83     if (!Sign(data, data_len, computed_digest, sizeof(computed_digest)))
     84         return false;
     85 
     86     return 0 == CRYPTO_memcmp(digest, computed_digest, SHA256_DIGEST_LENGTH);
     87 }
     88 
     89 }  // namespace keymaster
     90