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 "auth_encrypted_key_blob.h" 18 19 #include <keymaster/android_keymaster_utils.h> 20 #include <keymaster/authorization_set.h> 21 #include <keymaster/logger.h> 22 23 #include "ocb_utils.h" 24 25 namespace keymaster { 26 27 const uint32_t CURRENT_BLOB_VERSION = 0; 28 29 keymaster_error_t SerializeAuthEncryptedBlob(const KeymasterKeyBlob& encrypted_key_material, 30 const AuthorizationSet& hw_enforced, 31 const AuthorizationSet& sw_enforced, 32 33 const Buffer& nonce, const Buffer& tag, 34 KeymasterKeyBlob* key_blob) { 35 size_t size = 1 /* version byte */ + nonce.SerializedSize() + 36 encrypted_key_material.SerializedSize() + tag.SerializedSize() + 37 hw_enforced.SerializedSize() + sw_enforced.SerializedSize(); 38 39 if (!key_blob->Reset(size)) 40 return KM_ERROR_MEMORY_ALLOCATION_FAILED; 41 42 uint8_t* buf = key_blob->writable_data(); 43 const uint8_t* end = key_blob->key_material + key_blob->key_material_size; 44 45 *buf++ = CURRENT_BLOB_VERSION; 46 buf = nonce.Serialize(buf, end); 47 buf = encrypted_key_material.Serialize(buf, end); 48 buf = tag.Serialize(buf, end); 49 buf = hw_enforced.Serialize(buf, end); 50 buf = sw_enforced.Serialize(buf, end); 51 if (buf != key_blob->key_material + key_blob->key_material_size) 52 return KM_ERROR_UNKNOWN_ERROR; 53 54 return KM_ERROR_OK; 55 } 56 57 static keymaster_error_t DeserializeUnversionedBlob(const KeymasterKeyBlob& key_blob, 58 KeymasterKeyBlob* encrypted_key_material, 59 AuthorizationSet* hw_enforced, 60 AuthorizationSet* sw_enforced, Buffer* nonce, 61 Buffer* tag) { 62 const uint8_t* tmp = key_blob.key_material; 63 const uint8_t** buf_ptr = &tmp; 64 const uint8_t* end = tmp + key_blob.key_material_size; 65 66 if (!nonce->reserve(OCB_NONCE_LENGTH) || !tag->reserve(OCB_TAG_LENGTH)) 67 return KM_ERROR_MEMORY_ALLOCATION_FAILED; 68 69 if (!copy_from_buf(buf_ptr, end, nonce->peek_write(), OCB_NONCE_LENGTH) || 70 !encrypted_key_material->Deserialize(buf_ptr, end) || 71 !copy_from_buf(buf_ptr, end, tag->peek_write(), OCB_TAG_LENGTH) || 72 !hw_enforced->Deserialize(buf_ptr, end) || // 73 !sw_enforced->Deserialize(buf_ptr, end)) { 74 LOG_D("Failed to deserialize unversioned blob (may be a HW-backed key)", 0); 75 return KM_ERROR_INVALID_KEY_BLOB; 76 } 77 if (!nonce->advance_write(OCB_NONCE_LENGTH) || !tag->advance_write(OCB_TAG_LENGTH)) 78 return KM_ERROR_UNKNOWN_ERROR; 79 return KM_ERROR_OK; 80 } 81 82 keymaster_error_t DeserializeAuthEncryptedBlob(const KeymasterKeyBlob& key_blob, 83 KeymasterKeyBlob* encrypted_key_material, 84 AuthorizationSet* hw_enforced, 85 AuthorizationSet* sw_enforced, Buffer* nonce, 86 Buffer* tag) { 87 if (!key_blob.key_material || key_blob.key_material_size == 0) 88 return KM_ERROR_INVALID_KEY_BLOB; 89 90 const uint8_t* tmp = key_blob.key_material; 91 const uint8_t** buf_ptr = &tmp; 92 const uint8_t* end = tmp + key_blob.key_material_size; 93 94 if (end <= *buf_ptr) 95 return KM_ERROR_INVALID_KEY_BLOB; 96 97 uint8_t version = *(*buf_ptr)++; 98 if (version != CURRENT_BLOB_VERSION || // 99 !nonce->Deserialize(buf_ptr, end) || nonce->available_read() != OCB_NONCE_LENGTH || 100 !encrypted_key_material->Deserialize(buf_ptr, end) || // 101 !tag->Deserialize(buf_ptr, end) || tag->available_read() != OCB_TAG_LENGTH || 102 !hw_enforced->Deserialize(buf_ptr, end) || // 103 !sw_enforced->Deserialize(buf_ptr, end)) { 104 // This blob failed to parse. Either it's corrupted or it's a blob generated by an earlier 105 // version of keymaster using a previous blob format which did not include the version byte 106 // or the nonce or tag length fields. So we try to parse it as that previous version. 107 // 108 // Note that it's not really a problem if we erronously parse a corrupted blob, because 109 // decryption will fail the authentication check. 110 // 111 // A bigger potential problem is: What if a valid unversioned blob appears to parse 112 // correctly as a versioned blob? It would then be rejected during decryption, causing a 113 // valid key to become unusable. If this is a disk encryption key, upgrading to a keymaster 114 // version with the new format would destroy the user's data. 115 // 116 // What is the probability that an unversioned key could be successfully parsed as a version 117 // 0 key? The first 12 bytes of an unversioned key are the nonce, which, in the only 118 // keymaster version released with unversioned keys, is chosen randomly. In order for an 119 // unversioned key to parse as a version 0 key, the following must be true about the first 120 // five of those random bytes: 121 // 122 // 1. The first byte must be zero. This will happen with probability 1/2^8. 123 // 124 // 2. The second through fifth bytes must contain an unsigned integer value equal to 125 // NONCE_LENGTH. This will happen with probability 1/2^32. 126 // 127 // Based on those two checks alone, the probability of interpreting an unversioned blob as a 128 // version 0 blob is 1/2^40. That's small enough to be negligible, but there are additional 129 // checks which lower it further. 130 LOG_D("Failed to deserialize versioned key blob. Assuming unversioned.", 0); 131 return DeserializeUnversionedBlob(key_blob, encrypted_key_material, hw_enforced, 132 sw_enforced, nonce, tag); 133 } 134 return KM_ERROR_OK; 135 } 136 137 } // namespace keymaster 138