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 "aes_key.h" 18 19 #include <assert.h> 20 21 #include <keymaster/new> 22 23 #include <openssl/err.h> 24 #include <openssl/rand.h> 25 26 #include "aes_operation.h" 27 28 namespace keymaster { 29 30 AesEncryptionOperationFactory encrypt_factory; 31 AesDecryptionOperationFactory decrypt_factory; 32 33 OperationFactory* AesKeyFactory::GetOperationFactory(keymaster_purpose_t purpose) const { 34 switch (purpose) { 35 case KM_PURPOSE_ENCRYPT: 36 return &encrypt_factory; 37 case KM_PURPOSE_DECRYPT: 38 return &decrypt_factory; 39 default: 40 return nullptr; 41 } 42 } 43 44 keymaster_error_t AesKeyFactory::LoadKey(const KeymasterKeyBlob& key_material, 45 const AuthorizationSet& /* additional_params */, 46 const AuthorizationSet& hw_enforced, 47 const AuthorizationSet& sw_enforced, 48 UniquePtr<Key>* key) const { 49 if (!key) 50 return KM_ERROR_OUTPUT_PARAMETER_NULL; 51 52 uint32_t min_mac_length = 0; 53 if (hw_enforced.Contains(TAG_BLOCK_MODE, KM_MODE_GCM) || 54 sw_enforced.Contains(TAG_BLOCK_MODE, KM_MODE_GCM)) { 55 56 if (!hw_enforced.GetTagValue(TAG_MIN_MAC_LENGTH, &min_mac_length) && 57 !sw_enforced.GetTagValue(TAG_MIN_MAC_LENGTH, &min_mac_length)) { 58 59 LOG_E("AES-GCM key must have KM_TAG_MIN_MAC_LENGTH", 0); 60 return KM_ERROR_INVALID_KEY_BLOB; 61 } 62 } 63 64 keymaster_error_t error = KM_ERROR_OK; 65 key->reset(new (std::nothrow) AesKey(key_material, hw_enforced, sw_enforced, &error)); 66 if (!key->get()) 67 error = KM_ERROR_MEMORY_ALLOCATION_FAILED; 68 return error; 69 } 70 71 keymaster_error_t AesKeyFactory::validate_algorithm_specific_new_key_params( 72 const AuthorizationSet& key_description) const { 73 if (key_description.Contains(TAG_BLOCK_MODE, KM_MODE_GCM)) { 74 uint32_t min_tag_length; 75 if (!key_description.GetTagValue(TAG_MIN_MAC_LENGTH, &min_tag_length)) 76 return KM_ERROR_MISSING_MIN_MAC_LENGTH; 77 78 if (min_tag_length % 8 != 0) 79 return KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH; 80 81 if (min_tag_length < kMinGcmTagLength || min_tag_length > kMaxGcmTagLength) 82 return KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH; 83 } else { 84 // Not GCM 85 if (key_description.find(TAG_MIN_MAC_LENGTH) != -1) { 86 LOG_W("KM_TAG_MIN_MAC_LENGTH found for non AES-GCM key", 0); 87 return KM_ERROR_INVALID_TAG; 88 } 89 } 90 91 return KM_ERROR_OK; 92 } 93 94 } // namespace keymaster 95