/*
 * 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 "auth_encrypted_key_blob.h"

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

#include "ocb_utils.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
