// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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 "starboard/configuration.h"
#include "starboard/cryptography.h"
#include "starboard/log.h"
#include "starboard/memory.h"
#include "starboard/shared/starboard/cryptography/cryptography_internal.h"
#include "starboard/shared/starboard/cryptography/software_aes.h"
#include "starboard/string.h"

#if SB_API_VERSION < 4
#error "SbCryptography requires SB_API_VERSION >= 4."
#endif

using starboard::shared::starboard::cryptography::AES_KEY;
using starboard::shared::starboard::cryptography::AES_gcm128_init;
using starboard::shared::starboard::cryptography::Algorithm;
using starboard::shared::starboard::cryptography::kAlgorithmAes128Cbc;
using starboard::shared::starboard::cryptography::kAlgorithmAes128Ctr;
using starboard::shared::starboard::cryptography::kAlgorithmAes128Ecb;
using starboard::shared::starboard::cryptography::kAlgorithmAes128Gcm;

SbCryptographyTransformer SbCryptographyCreateTransformer(
    const char* algorithm,
    int block_size_bits,
    SbCryptographyDirection direction,
    SbCryptographyBlockCipherMode mode,
    const void* initialization_vector,
    int initialization_vector_size,
    const void* key,
    int key_size) {
  if (SbStringCompareAll(algorithm, kSbCryptographyAlgorithmAes) != 0) {
    SB_DLOG(WARNING) << "Unsupported algorithm: " << algorithm;
    return kSbCryptographyInvalidTransformer;
  }

  if (block_size_bits != 128) {
    SB_DLOG(WARNING) << "Unsupported block size: " << block_size_bits;
    return kSbCryptographyInvalidTransformer;
  }

  Algorithm combined_algorithm;
  if (mode == kSbCryptographyBlockCipherModeCbc) {
    combined_algorithm = kAlgorithmAes128Cbc;
  } else if (mode == kSbCryptographyBlockCipherModeCtr) {
    combined_algorithm = kAlgorithmAes128Ctr;
  } else if (mode == kSbCryptographyBlockCipherModeEcb) {
    combined_algorithm = kAlgorithmAes128Ecb;
  } else if (mode == kSbCryptographyBlockCipherModeGcm) {
    combined_algorithm = kAlgorithmAes128Gcm;
  } else {
    SB_DLOG(WARNING) << "Unsupported block cipher mode: " << mode;
    return kSbCryptographyInvalidTransformer;
  }

  if (mode == kSbCryptographyBlockCipherModeGcm ||
      mode == kSbCryptographyBlockCipherModeEcb) {
    if (initialization_vector_size != 0) {
      SB_DLOG(WARNING) << "Unsupported initialization_vector_size: "
                       << initialization_vector_size;
      return kSbCryptographyInvalidTransformer;
    }
  } else if (mode == kSbCryptographyBlockCipherModeCtr) {
    if (initialization_vector_size != 0 && initialization_vector_size != 12 &&
        initialization_vector_size != 16 && initialization_vector_size != 32) {
      SB_DLOG(WARNING) << "Unsupported CTR initialization_vector_size: "
                       << initialization_vector_size;
      return kSbCryptographyInvalidTransformer;
    }
  } else if (initialization_vector_size != block_size_bits / 8) {
    SB_DLOG(WARNING) << "Unsupported initialization_vector_size: "
                     << initialization_vector_size;
    return kSbCryptographyInvalidTransformer;
  }

  if (key_size != 16 && key_size != 24 && key_size != 32) {
    SB_DLOG(WARNING) << "Unsupported key_size: " << key_size;
    return kSbCryptographyInvalidTransformer;
  }

  AES_KEY aeskey = {0};
  int result = -1;
  if (direction == kSbCryptographyDirectionDecode &&
      mode != kSbCryptographyBlockCipherModeCtr &&
      mode != kSbCryptographyBlockCipherModeEcb &&
      mode != kSbCryptographyBlockCipherModeGcm) {
    result = AES_set_decrypt_key(key, key_size * 8, &aeskey);
  } else {
    result = AES_set_encrypt_key(key, key_size * 8, &aeskey);
  }

  if (result != 0) {
    SB_DLOG(WARNING) << "Error setting key: " << result;
    return kSbCryptographyInvalidTransformer;
  }

  SbCryptographyTransformer transformer =
      new SbCryptographyTransformerPrivate();
  SbMemorySet(transformer, 0, sizeof(transformer));
  transformer->key = aeskey;
  transformer->algorithm = combined_algorithm;
  transformer->direction = direction;
  if (initialization_vector_size) {
    SbMemoryCopy(transformer->ivec, initialization_vector,
                 initialization_vector_size);
  }

  if (transformer->algorithm == kAlgorithmAes128Gcm) {
    AES_gcm128_init(&transformer->gcm_context, &transformer->key,
                    direction == kSbCryptographyDirectionEncode ? 1 : 0);
  }

  return transformer;
}
