/*
 * Copyright (C) 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.
 */

#ifndef KEYSTORE_BLOB_H_
#define KEYSTORE_BLOB_H_

#include <stdint.h>

#include <openssl/aes.h>
#include <openssl/md5.h>

#include <keystore/keystore.h>

constexpr size_t kValueSize = 32768;
constexpr size_t kAesKeySize = 128 / 8;
constexpr size_t kGcmTagLength = 128 / 8;
constexpr size_t kGcmIvLength = 96 / 8;

/* Here is the file format. There are two parts in blob.value, the secret and
 * the description. The secret is stored in ciphertext, and its original size
 * can be found in blob.length. The description is stored after the secret in
 * plaintext, and its size is specified in blob.info. The total size of the two
 * parts must be no more than kValueSize bytes. The first field is the version,
 * the second is the blob's type, and the third byte is flags. Fields other
 * than blob.info, blob.length, and blob.value are modified by encryptBlob()
 * and decryptBlob(). Thus they should not be accessed from outside. */

struct __attribute__((packed)) blobv3 {
    uint8_t version;
    uint8_t type;
    uint8_t flags;
    uint8_t info;
    uint8_t initialization_vector[AES_BLOCK_SIZE];  // Only 96 bits is used, rest is zeroed.
    uint8_t aead_tag[kGcmTagLength];
    int32_t length;  // in network byte order, only for backward compatibility
    uint8_t value[kValueSize + AES_BLOCK_SIZE];
};

struct __attribute__((packed)) blobv2 {
    uint8_t version;
    uint8_t type;
    uint8_t flags;
    uint8_t info;
    uint8_t vector[AES_BLOCK_SIZE];
    uint8_t encrypted[0];  // Marks offset to encrypted data.
    uint8_t digest[MD5_DIGEST_LENGTH];
    uint8_t digested[0];  // Marks offset to digested data.
    int32_t length;       // in network byte order
    uint8_t value[kValueSize + AES_BLOCK_SIZE];
};

static_assert(sizeof(blobv3) == sizeof(blobv2) &&
                  offsetof(blobv3, initialization_vector) == offsetof(blobv2, vector) &&
                  offsetof(blobv3, aead_tag) == offsetof(blobv2, digest) &&
                  offsetof(blobv3, aead_tag) == offsetof(blobv2, encrypted) &&
                  offsetof(blobv3, length) == offsetof(blobv2, length) &&
                  offsetof(blobv3, value) == offsetof(blobv2, value),
              "Oops.  Blob layout changed.");

static const uint8_t CURRENT_BLOB_VERSION = 3;

typedef enum {
    TYPE_ANY = 0,  // meta type that matches anything
    TYPE_GENERIC = 1,
    TYPE_MASTER_KEY = 2,
    TYPE_KEY_PAIR = 3,
    TYPE_KEYMASTER_10 = 4,
    TYPE_KEY_CHARACTERISTICS = 5,
} BlobType;

class Entropy;

class Blob {
  public:
    Blob(const uint8_t* value, size_t valueLength, const uint8_t* info, uint8_t infoLength,
         BlobType type);
    explicit Blob(blobv3 b);
    Blob();

    ~Blob() { mBlob = {}; }

    const uint8_t* getValue() const { return mBlob.value; }

    int32_t getLength() const { return mBlob.length; }

    const uint8_t* getInfo() const { return mBlob.value + mBlob.length; }
    uint8_t getInfoLength() const { return mBlob.info; }

    uint8_t getVersion() const { return mBlob.version; }

    bool isEncrypted() const;
    void setEncrypted(bool encrypted);

    bool isSuperEncrypted() const;
    void setSuperEncrypted(bool superEncrypted);

    bool isCriticalToDeviceEncryption() const;
    void setCriticalToDeviceEncryption(bool critical);

    bool isFallback() const { return mBlob.flags & KEYSTORE_FLAG_FALLBACK; }
    void setFallback(bool fallback);

    void setVersion(uint8_t version) { mBlob.version = version; }
    BlobType getType() const { return BlobType(mBlob.type); }
    void setType(BlobType type) { mBlob.type = uint8_t(type); }

    ResponseCode writeBlob(const std::string& filename, const uint8_t* aes_key, State state,
                           Entropy* entropy);
    ResponseCode readBlob(const std::string& filename, const uint8_t* aes_key, State state);

  private:
    blobv3 mBlob;
};

#endif  // KEYSTORE_BLOB_H_
