/*
 * Copyright 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <keymaster/key_blob_utils/auth_encrypted_key_blob.h>

#include <keymaster/android_keymaster_utils.h>
#include <keymaster/authorization_set.h>
#include <keymaster/key_blob_utils/ocb_utils.h>
#include <keymaster/logger.h>


namespace keymaster {

const uint32_t CURRENT_BLOB_VERSION = 0;

keymaster_error_t SerializeAuthEncryptedBlob(const KeymasterKeyBlob& encrypted_key_material,
                                             const AuthorizationSet& hw_enforced,
                                             const AuthorizationSet& sw_enforced,

                                             const Buffer& nonce, const Buffer& tag,
                                             KeymasterKeyBlob* key_blob) {
    size_t size = 1 /* version byte */ + nonce.SerializedSize() +
                  encrypted_key_material.SerializedSize() + tag.SerializedSize() +
                  hw_enforced.SerializedSize() + sw_enforced.SerializedSize();

    if (!key_blob->Reset(size))
        return KM_ERROR_MEMORY_ALLOCATION_FAILED;

    uint8_t* buf = key_blob->writable_data();
    const uint8_t* end = key_blob->key_material + key_blob->key_material_size;

    *buf++ = CURRENT_BLOB_VERSION;
    buf = nonce.Serialize(buf, end);
    buf = encrypted_key_material.Serialize(buf, end);
    buf = tag.Serialize(buf, end);
    buf = hw_enforced.Serialize(buf, end);
    buf = sw_enforced.Serialize(buf, end);
    if (buf != key_blob->key_material + key_blob->key_material_size)
        return KM_ERROR_UNKNOWN_ERROR;

    return KM_ERROR_OK;
}

static keymaster_error_t DeserializeUnversionedBlob(const KeymasterKeyBlob& key_blob,
                                                    KeymasterKeyBlob* encrypted_key_material,
                                                    AuthorizationSet* hw_enforced,
                                                    AuthorizationSet* sw_enforced, Buffer* nonce,
                                                    Buffer* tag) {
    const uint8_t* tmp = key_blob.key_material;
    const uint8_t** buf_ptr = &tmp;
    const uint8_t* end = tmp + key_blob.key_material_size;

    if (!nonce->reserve(OCB_NONCE_LENGTH) || !tag->reserve(OCB_TAG_LENGTH))
        return KM_ERROR_MEMORY_ALLOCATION_FAILED;

    if (!copy_from_buf(buf_ptr, end, nonce->peek_write(), OCB_NONCE_LENGTH) ||
        !encrypted_key_material->Deserialize(buf_ptr, end) ||
        !copy_from_buf(buf_ptr, end, tag->peek_write(), OCB_TAG_LENGTH) ||
        !hw_enforced->Deserialize(buf_ptr, end) ||  //
        !sw_enforced->Deserialize(buf_ptr, end)) {
        LOG_D("Failed to deserialize unversioned blob (may be a HW-backed key)", 0);
        return KM_ERROR_INVALID_KEY_BLOB;
    }
    if (!nonce->advance_write(OCB_NONCE_LENGTH) || !tag->advance_write(OCB_TAG_LENGTH))
        return KM_ERROR_UNKNOWN_ERROR;
    return KM_ERROR_OK;
}

keymaster_error_t DeserializeAuthEncryptedBlob(const KeymasterKeyBlob& key_blob,
                                               KeymasterKeyBlob* encrypted_key_material,
                                               AuthorizationSet* hw_enforced,
                                               AuthorizationSet* sw_enforced, Buffer* nonce,
                                               Buffer* tag) {
    if (!key_blob.key_material || key_blob.key_material_size == 0)
        return KM_ERROR_INVALID_KEY_BLOB;

    const uint8_t* tmp = key_blob.key_material;
    const uint8_t** buf_ptr = &tmp;
    const uint8_t* end = tmp + key_blob.key_material_size;

    if (end <= *buf_ptr)
        return KM_ERROR_INVALID_KEY_BLOB;

    uint8_t version = *(*buf_ptr)++;
    if (version != CURRENT_BLOB_VERSION ||  //
        !nonce->Deserialize(buf_ptr, end) || nonce->available_read() != OCB_NONCE_LENGTH ||
        !encrypted_key_material->Deserialize(buf_ptr, end) ||  //
        !tag->Deserialize(buf_ptr, end) || tag->available_read() != OCB_TAG_LENGTH ||
        !hw_enforced->Deserialize(buf_ptr, end) ||  //
        !sw_enforced->Deserialize(buf_ptr, end)) {
        // This blob failed to parse.  Either it's corrupted or it's a blob generated by an earlier
        // version of keymaster using a previous blob format which did not include the version byte
        // or the nonce or tag length fields.  So we try to parse it as that previous version.
        //
        // Note that it's not really a problem if we erronously parse a corrupted blob, because
        // decryption will fail the authentication check.
        //
        // A bigger potential problem is: What if a valid unversioned blob appears to parse
        // correctly as a versioned blob?  It would then be rejected during decryption, causing a
        // valid key to become unusable.  If this is a disk encryption key, upgrading to a keymaster
        // version with the new format would destroy the user's data.
        //
        // What is the probability that an unversioned key could be successfully parsed as a version
        // 0 key?  The first 12 bytes of an unversioned key are the nonce, which, in the only
        // keymaster version released with unversioned keys, is chosen randomly.  In order for an
        // unversioned key to parse as a version 0 key, the following must be true about the first
        // five of those random bytes:
        //
        // 1.  The first byte must be zero.  This will happen with probability 1/2^8.
        //
        // 2.  The second through fifth bytes must contain an unsigned integer value equal to
        //     NONCE_LENGTH.  This will happen with probability 1/2^32.
        //
        // Based on those two checks alone, the probability of interpreting an unversioned blob as a
        // version 0 blob is 1/2^40.  That's small enough to be negligible, but there are additional
        // checks which lower it further.
        LOG_D("Failed to deserialize versioned key blob.  Assuming unversioned.", 0);
        return DeserializeUnversionedBlob(key_blob, encrypted_key_material, hw_enforced,
                                          sw_enforced, nonce, tag);
    }
    return KM_ERROR_OK;
}

}  // namespace keymaster
