1 /* 2 * Copyright 2014 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 <keymaster/km_openssl/hmac_key.h> 18 19 #include <keymaster/new.h> 20 21 #include <openssl/err.h> 22 #include <openssl/rand.h> 23 24 #include "hmac_operation.h" 25 26 namespace keymaster { 27 28 static HmacSignOperationFactory sign_factory; 29 static HmacVerifyOperationFactory verify_factory; 30 31 OperationFactory* HmacKeyFactory::GetOperationFactory(keymaster_purpose_t purpose) const { 32 switch (purpose) { 33 case KM_PURPOSE_SIGN: 34 return &sign_factory; 35 case KM_PURPOSE_VERIFY: 36 return &verify_factory; 37 default: 38 return nullptr; 39 } 40 } 41 42 keymaster_error_t HmacKeyFactory::LoadKey(KeymasterKeyBlob&& key_material, 43 const AuthorizationSet& /* additional_params */, 44 AuthorizationSet&& hw_enforced, 45 AuthorizationSet&& sw_enforced, 46 UniquePtr<Key>* key) const { 47 if (!key) 48 return KM_ERROR_OUTPUT_PARAMETER_NULL; 49 50 uint32_t min_mac_length; 51 if (!hw_enforced.GetTagValue(TAG_MIN_MAC_LENGTH, &min_mac_length) && 52 !sw_enforced.GetTagValue(TAG_MIN_MAC_LENGTH, &min_mac_length)) { 53 LOG_E("HMAC key must have KM_TAG_MIN_MAC_LENGTH", 0); 54 return KM_ERROR_INVALID_KEY_BLOB; 55 } 56 57 key->reset(new (std::nothrow) HmacKey(move(key_material), move(hw_enforced), move(sw_enforced), 58 this)); 59 if (!key->get()) 60 return KM_ERROR_MEMORY_ALLOCATION_FAILED; 61 return KM_ERROR_OK; 62 } 63 64 keymaster_error_t HmacKeyFactory::validate_algorithm_specific_new_key_params( 65 const AuthorizationSet& key_description) const { 66 uint32_t min_mac_length_bits; 67 if (!key_description.GetTagValue(TAG_MIN_MAC_LENGTH, &min_mac_length_bits)) 68 return KM_ERROR_MISSING_MIN_MAC_LENGTH; 69 70 keymaster_digest_t digest; 71 if (!key_description.GetTagValue(TAG_DIGEST, &digest)) { 72 LOG_E("%d digests specified for HMAC key", key_description.GetTagCount(TAG_DIGEST)); 73 return KM_ERROR_UNSUPPORTED_DIGEST; 74 } 75 76 size_t hash_size_bits = 0; 77 switch (digest) { 78 case KM_DIGEST_NONE: 79 return KM_ERROR_UNSUPPORTED_DIGEST; 80 case KM_DIGEST_MD5: 81 hash_size_bits = 128; 82 break; 83 case KM_DIGEST_SHA1: 84 hash_size_bits = 160; 85 break; 86 case KM_DIGEST_SHA_2_224: 87 hash_size_bits = 224; 88 break; 89 case KM_DIGEST_SHA_2_256: 90 hash_size_bits = 256; 91 break; 92 case KM_DIGEST_SHA_2_384: 93 hash_size_bits = 384; 94 break; 95 case KM_DIGEST_SHA_2_512: 96 hash_size_bits = 512; 97 break; 98 }; 99 100 if (hash_size_bits == 0) { 101 // digest was not matched 102 return KM_ERROR_UNSUPPORTED_DIGEST; 103 } 104 105 if (min_mac_length_bits % 8 != 0 || min_mac_length_bits > hash_size_bits) 106 return KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH; 107 108 if (min_mac_length_bits < kMinHmacLengthBits) 109 return KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH; 110 111 return KM_ERROR_OK; 112 } 113 114 } // namespace keymaster 115