// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#include "crypto.h"

#include <openssl/conf.h>
#include <openssl/evp.h>

/**
 * Get EVP_CIPHER type pointer defined by key_len and mode.
 * If the selected cipher is not supported, the AES-128 ECB type is returned.
 *
 * @param  key_len   Encryption key length in bytes (16, 24, 32)
 * @param  mode      AES cipher mode @see crypto_mode.
 * @return Pointer to EVP_CIPHER type
 */
static const EVP_CIPHER *crypto_get_EVP_cipher(int key_len,
                                               crypto_mode_t mode) {
  const EVP_CIPHER *cipher;

  if (mode == kCryptoAesCbc) {
    if (key_len == 32) {
      cipher = EVP_aes_256_cbc();
    } else if (key_len == 24) {
      cipher = EVP_aes_192_cbc();
    } else {  // key_len = 16
      cipher = EVP_aes_128_cbc();
    }
  } else if (mode == kCryptoAesCfb) {
    if (key_len == 32) {
      cipher = EVP_aes_256_cfb128();
    } else if (key_len == 24) {
      cipher = EVP_aes_192_cfb128();
    } else {  // key_len = 16
      cipher = EVP_aes_128_cfb128();
    }
  } else if (mode == kCryptoAesOfb) {
    if (key_len == 32) {
      cipher = EVP_aes_256_ofb();
    } else if (key_len == 24) {
      cipher = EVP_aes_192_ofb();
    } else {  // key_len = 16
      cipher = EVP_aes_128_ofb();
    }
  } else if (mode == kCryptoAesCtr) {
    if (key_len == 32) {
      cipher = EVP_aes_256_ctr();
    } else if (key_len == 24) {
      cipher = EVP_aes_192_ctr();
    } else {  // key_len = 16
      cipher = EVP_aes_128_ctr();
    }
  } else {  // kCryptoAesEcb
    if (key_len == 32) {
      cipher = EVP_aes_256_ecb();
    } else if (key_len == 24) {
      cipher = EVP_aes_192_ecb();
    } else {  // key_len = 16
      cipher = EVP_aes_128_ecb();
    }
  }

  return cipher;
}

int crypto_encrypt(unsigned char *output, const unsigned char *iv,
                   const unsigned char *input, int input_len,
                   const unsigned char *key, int key_len, crypto_mode_t mode) {
  EVP_CIPHER_CTX *ctx;
  int ret;
  int len, output_len;

  // Create new cipher context
  ctx = EVP_CIPHER_CTX_new();
  if (!ctx) {
    printf("ERROR: Creation of cipher context failed\n");
    return -1;
  }

  // Get cipher
  const EVP_CIPHER *cipher = crypto_get_EVP_cipher(key_len, mode);

  // Init encryption context
  ret = EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv);

  if (ret != 1) {
    printf("ERROR: Initialization of encryption context failed\n");
    return -1;
  }

  // Disable padding - It is safe to do so here because we only ever encrypt
  // multiples of 16 bytes (the block size).
  EVP_CIPHER_CTX_set_padding(ctx, 0);

  // Provide encryption input, get first output bytes
  ret = EVP_EncryptUpdate(ctx, output, &output_len, input, input_len);
  if (ret != 1) {
    printf("ERROR: Encryption operation failed\n");
    return -1;
  }

  // Finalize encryption, further bytes might be written
  ret = EVP_EncryptFinal_ex(ctx, output + output_len, &len);
  if (ret != 1) {
    printf("ERROR: Encryption finalizing failed\n");
    return -1;
  }
  output_len += len;

  // Free
  EVP_CIPHER_CTX_free(ctx);

  return output_len;
}

int crypto_decrypt(unsigned char *output, const unsigned char *iv,
                   const unsigned char *input, int input_len,
                   const unsigned char *key, int key_len, crypto_mode_t mode) {
  EVP_CIPHER_CTX *ctx;
  int ret;
  int len, output_len;

  // Create new cipher context
  ctx = EVP_CIPHER_CTX_new();
  if (!ctx) {
    printf("ERROR: Creation of cipher context failed\n");
    return -1;
  }

  // Get cipher
  const EVP_CIPHER *cipher = crypto_get_EVP_cipher(key_len, mode);

  // Init decryption context
  ret = EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv);
  if (ret != 1) {
    printf("ERROR: Initialization of decryption context failed\n");
    return -1;
  }

  // Disable padding - It is safe to do so here because we only ever decrypt
  // multiples of 16 bytes (the block size).
  EVP_CIPHER_CTX_set_padding(ctx, 0);

  // Provide decryption input, get first output bytes
  ret = EVP_DecryptUpdate(ctx, output, &output_len, input, input_len);
  if (ret != 1) {
    printf("ERROR: Decryption operation failed\n");
    return -1;
  }

  // Finalize decryption, further bytes might be written
  ret = EVP_DecryptFinal_ex(ctx, output + output_len, &len);
  if (ret != 1) {
    printf("ERROR: Decryption finalizing failed\n");
    return -1;
  }
  output_len += len;

  // Free
  EVP_CIPHER_CTX_free(ctx);

  return output_len;
}
