// 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/shared/starboard/cryptography/cryptography_internal.h"
#include "starboard/shared/starboard/cryptography/software_aes.h"

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

using starboard::shared::starboard::cryptography::AES_cbc_encrypt;
using starboard::shared::starboard::cryptography::AES_ctr128_encrypt;
using starboard::shared::starboard::cryptography::AES_decrypt;
using starboard::shared::starboard::cryptography::AES_encrypt;
using starboard::shared::starboard::cryptography::AES_gcm128_decrypt;
using starboard::shared::starboard::cryptography::AES_gcm128_encrypt;
using starboard::shared::starboard::cryptography::kAlgorithmAes128Cbc;
using starboard::shared::starboard::cryptography::kAlgorithmAes128Ctr;
using starboard::shared::starboard::cryptography::kAlgorithmAes128Ecb;
using starboard::shared::starboard::cryptography::kAlgorithmAes128Gcm;

int SbCryptographyTransform(SbCryptographyTransformer transformer,
                            const void* in_data,
                            int in_data_size,
                            void* out_data) {
  if (!SbCryptographyIsTransformerValid(transformer) || !in_data || !out_data) {
    return -1;
  }

  if (in_data_size == 0) {
    return 0;
  }

  switch (transformer->algorithm) {
    case kAlgorithmAes128Cbc:
      AES_cbc_encrypt(in_data, out_data, in_data_size, &(transformer->key),
                      transformer->ivec,
                      transformer->direction == kSbCryptographyDirectionEncode ?
                      SB_AES_ENCRYPT : SB_AES_DECRYPT);
      break;

    case kAlgorithmAes128Ctr:
      AES_ctr128_encrypt(in_data, out_data, in_data_size, &(transformer->key),
                         transformer->ivec, transformer->ecount_buf,
                         &transformer->counter);
      break;

    case kAlgorithmAes128Ecb:
      if (in_data_size % 16 != 0) {
        SB_DLOG(ERROR) << "ECB called with a non-multiple of the block size.";
        return -1;
      }

      if (transformer->direction == kSbCryptographyDirectionEncode) {
        AES_encrypt(in_data, out_data, &transformer->key);
      } else if (transformer->direction == kSbCryptographyDirectionDecode) {
        AES_decrypt(in_data, out_data, &transformer->key);
      } else {
        SB_NOTREACHED();
      }
      break;

    case kAlgorithmAes128Gcm:
      if (transformer->direction == kSbCryptographyDirectionEncode) {
        AES_gcm128_encrypt(&transformer->gcm_context, &transformer->key,
                           in_data, out_data, in_data_size);
      } else if (transformer->direction == kSbCryptographyDirectionDecode) {
        AES_gcm128_decrypt(&transformer->gcm_context, &transformer->key,
                           in_data, out_data, in_data_size);
      } else {
        SB_NOTREACHED();
      }
      break;

    default:
      SB_NOTREACHED();
      return -1;
  }

  return in_data_size;
}
