// Copyright 2017 The Cobalt Authors. 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"

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;

namespace {
inline void* AddPtr(void* pointer, int value) {
  return reinterpret_cast<char*>(pointer) + value;
}

inline const void* AddPtr(const void* pointer, int value) {
  return reinterpret_cast<const char*>(pointer) + value;
}
}  // namespace

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) {
        const void* in = in_data;
        void* out = out_data;
        for (int i = 0, blocks = in_data_size / 16; i < blocks; ++i) {
          AES_encrypt(in, out, &transformer->key);
          in = AddPtr(in, 16);
          out = AddPtr(out, 16);
        }
      } else if (transformer->direction == kSbCryptographyDirectionDecode) {
        const void* in = in_data;
        void* out = out_data;
        for (int i = 0, blocks = in_data_size / 16; i < blocks; ++i) {
          AES_decrypt(in, out, &transformer->key);
          in = AddPtr(in, 16);
          out = AddPtr(out, 16);
        }
      } 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;
}
