Home | History | Annotate | Download | only in keymaster
      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 <assert.h>
     18 
     19 #include <openssl/aes.h>
     20 #include <openssl/sha.h>
     21 
     22 #include <keymaster/google_keymaster_utils.h>
     23 #include <keymaster/key_blob.h>
     24 
     25 #include "ae.h"
     26 
     27 namespace keymaster {
     28 
     29 class KeyBlob::AeCtx {
     30   public:
     31     AeCtx() : ctx_(ae_allocate(NULL)) {}
     32     ~AeCtx() {
     33         ae_clear(ctx_);
     34         ae_free(ctx_);
     35     }
     36 
     37     ae_ctx* get() { return ctx_; }
     38 
     39   private:
     40     ae_ctx* ctx_;
     41 };
     42 
     43 const size_t KeyBlob::NONCE_LENGTH;
     44 const size_t KeyBlob::TAG_LENGTH;
     45 
     46 KeyBlob::KeyBlob(const AuthorizationSet& enforced, const AuthorizationSet& unenforced,
     47                  const AuthorizationSet& hidden, const keymaster_key_blob_t& key,
     48                  const keymaster_key_blob_t& master_key, const uint8_t nonce[NONCE_LENGTH])
     49     : error_(KM_ERROR_OK), nonce_(new uint8_t[NONCE_LENGTH]), tag_(new uint8_t[TAG_LENGTH]),
     50       enforced_(enforced), unenforced_(unenforced), hidden_(hidden) {
     51     if (!nonce_.get() || !tag_.get()) {
     52         error_ = KM_ERROR_MEMORY_ALLOCATION_FAILED;
     53         return;
     54     }
     55     error_ = KM_ERROR_OK;
     56 
     57     if (enforced_.is_valid() == AuthorizationSet::ALLOCATION_FAILURE ||
     58         unenforced_.is_valid() == AuthorizationSet::ALLOCATION_FAILURE ||
     59         hidden_.is_valid() == AuthorizationSet::ALLOCATION_FAILURE) {
     60         error_ = KM_ERROR_MEMORY_ALLOCATION_FAILED;
     61         return;
     62     }
     63 
     64     if (enforced_.is_valid() != AuthorizationSet::OK ||
     65         unenforced_.is_valid() != AuthorizationSet::OK ||
     66         hidden_.is_valid() != AuthorizationSet::OK) {
     67         error_ = KM_ERROR_UNKNOWN_ERROR;
     68         return;
     69     }
     70 
     71     if (!ExtractKeyCharacteristics())
     72         return;
     73 
     74     key_material_length_ = key.key_material_size;
     75     key_material_.reset(new uint8_t[key_material_length_]);
     76     encrypted_key_material_.reset(new uint8_t[key_material_length_]);
     77 
     78     if (!key_material_.get() || !encrypted_key_material_.get() || !nonce_.get() || !tag_.get()) {
     79         error_ = KM_ERROR_MEMORY_ALLOCATION_FAILED;
     80         return;
     81     }
     82 
     83     memcpy(nonce_.get(), nonce, NONCE_LENGTH);
     84     memcpy(key_material_.get(), key.key_material, key_material_length_);
     85     EncryptKey(master_key);
     86 }
     87 
     88 KeyBlob::KeyBlob(const keymaster_key_blob_t& key, const AuthorizationSet& hidden,
     89                  const keymaster_key_blob_t& master_key)
     90     : nonce_(new uint8_t[NONCE_LENGTH]), tag_(new uint8_t[TAG_LENGTH]), hidden_(hidden) {
     91     if (!nonce_.get() || !tag_.get()) {
     92         error_ = KM_ERROR_MEMORY_ALLOCATION_FAILED;
     93         return;
     94     }
     95     error_ = KM_ERROR_OK;
     96 
     97     const uint8_t* p = key.key_material;
     98     if (!Deserialize(&p, key.key_material + key.key_material_size))
     99         return;
    100     DecryptKey(master_key);
    101 }
    102 
    103 KeyBlob::KeyBlob(const uint8_t* key_blob, size_t blob_size)
    104     : nonce_(new uint8_t[NONCE_LENGTH]), tag_(new uint8_t[TAG_LENGTH]) {
    105     if (!nonce_.get() || !tag_.get()) {
    106         error_ = KM_ERROR_MEMORY_ALLOCATION_FAILED;
    107         return;
    108     }
    109     error_ = KM_ERROR_OK;
    110 
    111     if (!Deserialize(&key_blob, key_blob + blob_size))
    112         return;
    113 }
    114 
    115 size_t KeyBlob::SerializedSize() const {
    116     return NONCE_LENGTH + sizeof(uint32_t) + key_material_length() + TAG_LENGTH +
    117            enforced_.SerializedSize() + unenforced_.SerializedSize();
    118 }
    119 
    120 uint8_t* KeyBlob::Serialize(uint8_t* buf, const uint8_t* end) const {
    121     const uint8_t* start = buf;
    122     buf = append_to_buf(buf, end, nonce(), NONCE_LENGTH);
    123     buf = append_size_and_data_to_buf(buf, end, encrypted_key_material(), key_material_length());
    124     buf = append_to_buf(buf, end, tag(), TAG_LENGTH);
    125     buf = enforced_.Serialize(buf, end);
    126     buf = unenforced_.Serialize(buf, end);
    127     assert(buf - start == static_cast<ptrdiff_t>(SerializedSize()));
    128     return buf;
    129 }
    130 
    131 bool KeyBlob::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
    132     UniquePtr<uint8_t[]> tmp_key_ptr;
    133     if (!copy_from_buf(buf_ptr, end, nonce_.get(), NONCE_LENGTH) ||
    134         !copy_size_and_data_from_buf(buf_ptr, end, &key_material_length_, &tmp_key_ptr) ||
    135         !copy_from_buf(buf_ptr, end, tag_.get(), TAG_LENGTH) ||
    136         !enforced_.Deserialize(buf_ptr, end) || !unenforced_.Deserialize(buf_ptr, end)) {
    137         error_ = KM_ERROR_INVALID_KEY_BLOB;
    138         return false;
    139     }
    140 
    141     if (!ExtractKeyCharacteristics())
    142         return false;
    143 
    144     encrypted_key_material_.reset(tmp_key_ptr.release());
    145     key_material_.reset(new uint8_t[key_material_length_]);
    146     return true;
    147 }
    148 
    149 void KeyBlob::EncryptKey(const keymaster_key_blob_t& master_key) {
    150     UniquePtr<AeCtx> ctx(InitializeKeyWrappingContext(master_key, &error_));
    151     if (error_ != KM_ERROR_OK)
    152         return;
    153 
    154     int ae_err = ae_encrypt(ctx->get(), nonce_.get(), key_material(), key_material_length(),
    155                             NULL /* additional data */, 0 /* additional data length */,
    156                             encrypted_key_material_.get(), tag_.get(), 1 /* final */);
    157     if (ae_err < 0) {
    158         error_ = KM_ERROR_UNKNOWN_ERROR;
    159         return;
    160     }
    161     assert(ae_err == static_cast<int>(key_material_length_));
    162     error_ = KM_ERROR_OK;
    163 }
    164 
    165 void KeyBlob::DecryptKey(const keymaster_key_blob_t& master_key) {
    166     UniquePtr<AeCtx> ctx(InitializeKeyWrappingContext(master_key, &error_));
    167     if (error_ != KM_ERROR_OK)
    168         return;
    169 
    170     int ae_err =
    171         ae_decrypt(ctx->get(), nonce_.get(), encrypted_key_material(), key_material_length(),
    172                    NULL /* additional data */, 0 /* additional data length */, key_material_.get(),
    173                    tag_.get(), 1 /* final */);
    174     if (ae_err == AE_INVALID) {
    175         // Authentication failed!  Decryption probably succeeded(ish), but we don't want to return
    176         // any data when the authentication fails, so clear it.
    177         memset_s(key_material_.get(), 0, key_material_length());
    178         error_ = KM_ERROR_INVALID_KEY_BLOB;
    179         return;
    180     } else if (ae_err < 0) {
    181         error_ = KM_ERROR_UNKNOWN_ERROR;
    182         return;
    183     }
    184     assert(ae_err == static_cast<int>(key_material_length()));
    185     error_ = KM_ERROR_OK;
    186 }
    187 
    188 KeyBlob::AeCtx* KeyBlob::InitializeKeyWrappingContext(const keymaster_key_blob_t& master_key,
    189                                                       keymaster_error_t* error) const {
    190     size_t derivation_data_length;
    191     UniquePtr<const uint8_t[]> derivation_data(BuildDerivationData(&derivation_data_length));
    192     if (derivation_data.get() == NULL) {
    193         *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
    194         return NULL;
    195     }
    196 
    197     *error = KM_ERROR_OK;
    198     UniquePtr<AeCtx> ctx(new AeCtx);
    199 
    200     SHA256_CTX sha256_ctx;
    201     UniquePtr<uint8_t[]> hash_buf(new uint8_t[SHA256_DIGEST_LENGTH]);
    202     Eraser hash_eraser(hash_buf.get(), SHA256_DIGEST_LENGTH);
    203     UniquePtr<uint8_t[]> derived_key(new uint8_t[AES_BLOCK_SIZE]);
    204     Eraser derived_key_eraser(derived_key.get(), AES_BLOCK_SIZE);
    205 
    206     if (ctx.get() == NULL || hash_buf.get() == NULL || derived_key.get() == NULL) {
    207         *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
    208         return NULL;
    209     }
    210 
    211     Eraser sha256_ctx_eraser(sha256_ctx);
    212 
    213     // Hash derivation data.
    214     SHA256_Init(&sha256_ctx);
    215     SHA256_Update(&sha256_ctx, derivation_data.get(), derivation_data_length);
    216     SHA256_Final(hash_buf.get(), &sha256_ctx);
    217 
    218     // Encrypt hash with master key to build derived key.
    219     AES_KEY aes_key;
    220     Eraser aes_key_eraser(AES_KEY);
    221     if (AES_set_encrypt_key(master_key.key_material, master_key.key_material_size * 8, &aes_key) !=
    222         0) {
    223         *error = KM_ERROR_UNKNOWN_ERROR;
    224         return NULL;
    225     }
    226     AES_encrypt(hash_buf.get(), derived_key.get(), &aes_key);
    227 
    228     // Set up AES OCB context using derived key.
    229     if (ae_init(ctx->get(), derived_key.get(), AES_BLOCK_SIZE, NONCE_LENGTH, TAG_LENGTH) ==
    230         AE_SUCCESS)
    231         return ctx.release();
    232     else {
    233         memset_s(ctx.get(), 0, ae_ctx_sizeof());
    234         return NULL;
    235     }
    236 }
    237 
    238 const uint8_t* KeyBlob::BuildDerivationData(size_t* derivation_data_length) const {
    239     *derivation_data_length =
    240         hidden_.SerializedSize() + enforced_.SerializedSize() + unenforced_.SerializedSize();
    241     uint8_t* derivation_data = new uint8_t[*derivation_data_length];
    242     if (derivation_data != NULL) {
    243         uint8_t* buf = derivation_data;
    244         uint8_t* end = derivation_data + *derivation_data_length;
    245         buf = hidden_.Serialize(buf, end);
    246         buf = enforced_.Serialize(buf, end);
    247         buf = unenforced_.Serialize(buf, end);
    248     }
    249     return derivation_data;
    250 }
    251 
    252 bool KeyBlob::ExtractKeyCharacteristics() {
    253     if (!enforced_.GetTagValue(TAG_ALGORITHM, &algorithm_) &&
    254         !unenforced_.GetTagValue(TAG_ALGORITHM, &algorithm_)) {
    255         error_ = KM_ERROR_UNSUPPORTED_ALGORITHM;
    256         return false;
    257     }
    258     if (!enforced_.GetTagValue(TAG_KEY_SIZE, &key_size_bits_) &&
    259         !unenforced_.GetTagValue(TAG_KEY_SIZE, &key_size_bits_)) {
    260         error_ = KM_ERROR_UNSUPPORTED_KEY_SIZE;
    261         return false;
    262     }
    263     return true;
    264 }
    265 
    266 }  // namespace keymaster
    267