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/aes_key.h> 18 19 #include <assert.h> 20 21 #include <keymaster/new.h> 22 23 #include <openssl/err.h> 24 #include <openssl/rand.h> 25 26 #include "aes_operation.h" 27 28 namespace keymaster { 29 30 static AesOperationFactory encrypt_factory(KM_PURPOSE_ENCRYPT); 31 static AesOperationFactory decrypt_factory(KM_PURPOSE_DECRYPT); 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(KeymasterKeyBlob&& key_material, 45 const AuthorizationSet& /* additional_params */, 46 AuthorizationSet&& hw_enforced, 47 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(move(key_material), move(hw_enforced), move(sw_enforced), 66 this)); 67 if (!key->get()) 68 error = KM_ERROR_MEMORY_ALLOCATION_FAILED; 69 return error; 70 } 71 72 keymaster_error_t AesKeyFactory::validate_algorithm_specific_new_key_params( 73 const AuthorizationSet& key_description) const { 74 if (key_description.Contains(TAG_BLOCK_MODE, KM_MODE_GCM)) { 75 uint32_t min_tag_length; 76 if (!key_description.GetTagValue(TAG_MIN_MAC_LENGTH, &min_tag_length)) 77 return KM_ERROR_MISSING_MIN_MAC_LENGTH; 78 79 if (min_tag_length % 8 != 0) 80 return KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH; 81 82 if (min_tag_length < kMinGcmTagLength || min_tag_length > kMaxGcmTagLength) 83 return KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH; 84 } else { 85 // Not GCM 86 if (key_description.find(TAG_MIN_MAC_LENGTH) != -1) { 87 LOG_W("KM_TAG_MIN_MAC_LENGTH found for non AES-GCM key", 0); 88 return KM_ERROR_INVALID_TAG; 89 } 90 } 91 92 return KM_ERROR_OK; 93 } 94 95 } // namespace keymaster 96