/*
 * 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_E("Failed to deserialize unversioned blob", 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_I("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
