// Copyright 1995-2016 The OpenSSL Project 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
//
//     https://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 <openssl/cipher.h>
#include <openssl/des.h>
#include <openssl/nid.h>

#include "../des/internal.h"
#include "../fipsmodule/cipher/internal.h"
#include "internal.h"


typedef struct {
  union {
    double align;
    DES_key_schedule ks;
  } ks;
} EVP_DES_KEY;

static int des_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
                        const uint8_t *iv, int enc) {
  EVP_DES_KEY *dat = (EVP_DES_KEY *)ctx->cipher_data;
  DES_set_key_ex(key, &dat->ks.ks);
  return 1;
}

static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
                          size_t in_len) {
  EVP_DES_KEY *dat = (EVP_DES_KEY *)ctx->cipher_data;
  DES_ncbc_encrypt_ex(in, out, in_len, &dat->ks.ks, ctx->iv, ctx->encrypt);
  return 1;
}

static const EVP_CIPHER evp_des_cbc = {
    /*nid=*/NID_des_cbc,
    /*block_size=*/8,
    /*key_len=*/8,
    /*iv_len=*/8,
    /*ctx_size=*/sizeof(EVP_DES_KEY),
    /*flags=*/EVP_CIPH_CBC_MODE,
    /*init=*/des_init_key,
    /*cipher=*/des_cbc_cipher,
    /*cleanup=*/nullptr,
    /*ctrl=*/nullptr,
};

const EVP_CIPHER *EVP_des_cbc(void) { return &evp_des_cbc; }

static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
                          size_t in_len) {
  if (in_len < ctx->cipher->block_size) {
    return 1;
  }
  in_len -= ctx->cipher->block_size;

  EVP_DES_KEY *dat = (EVP_DES_KEY *)ctx->cipher_data;
  for (size_t i = 0; i <= in_len; i += ctx->cipher->block_size) {
    DES_ecb_encrypt_ex(in + i, out + i, &dat->ks.ks, ctx->encrypt);
  }
  return 1;
}

static const EVP_CIPHER evp_des_ecb = {
    /*nid=*/NID_des_ecb,
    /*block_size=*/8,
    /*key_len=*/8,
    /*iv_len=*/0,
    /*ctx_size=*/sizeof(EVP_DES_KEY),
    /*flags=*/EVP_CIPH_ECB_MODE,
    /*init=*/des_init_key,
    /*cipher=*/des_ecb_cipher,
    /*cleanup=*/nullptr,
    /*ctrl=*/nullptr,
};

const EVP_CIPHER *EVP_des_ecb(void) { return &evp_des_ecb; }

typedef struct {
  union {
    double align;
    DES_key_schedule ks[3];
  } ks;
} DES_EDE_KEY;

static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
                             const uint8_t *iv, int enc) {
  DES_EDE_KEY *dat = (DES_EDE_KEY *)ctx->cipher_data;
  DES_set_key_ex(key, &dat->ks.ks[0]);
  DES_set_key_ex(key + 8, &dat->ks.ks[1]);
  DES_set_key_ex(key + 16, &dat->ks.ks[2]);
  return 1;
}

static int des_ede3_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out,
                               const uint8_t *in, size_t in_len) {
  DES_EDE_KEY *dat = (DES_EDE_KEY *)ctx->cipher_data;
  DES_ede3_cbc_encrypt_ex(in, out, in_len, &dat->ks.ks[0], &dat->ks.ks[1],
                          &dat->ks.ks[2], ctx->iv, ctx->encrypt);
  return 1;
}

static const EVP_CIPHER evp_des_ede3_cbc = {
    /*nid=*/NID_des_ede3_cbc,
    /*block_size=*/8,
    /*key_len=*/24,
    /*iv_len=*/8,
    /*ctx_size=*/sizeof(DES_EDE_KEY),
    /*flags=*/EVP_CIPH_CBC_MODE,
    /*init=*/des_ede3_init_key,
    /*cipher=*/des_ede3_cbc_cipher,
    /*cleanup=*/nullptr,
    /*ctrl=*/nullptr,
};

const EVP_CIPHER *EVP_des_ede3_cbc(void) { return &evp_des_ede3_cbc; }

static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
                            const uint8_t *iv, int enc) {
  DES_EDE_KEY *dat = (DES_EDE_KEY *)ctx->cipher_data;
  // 2-DES is 3-DES with the first key used twice.
  DES_set_key_ex(key, &dat->ks.ks[0]);
  DES_set_key_ex(key + 8, &dat->ks.ks[1]);
  DES_set_key_ex(key, &dat->ks.ks[2]);
  return 1;
}

static const EVP_CIPHER evp_des_ede_cbc = {
    /*nid=*/NID_des_ede_cbc,
    /*block_size=*/8,
    /*key_len=*/16,
    /*iv_len=*/8,
    /*ctx_size=*/sizeof(DES_EDE_KEY),
    /*flags=*/EVP_CIPH_CBC_MODE,
    /*init=*/des_ede_init_key,
    /*cipher=*/des_ede3_cbc_cipher,
    /*cleanup=*/nullptr,
    /*ctrl=*/nullptr,
};

const EVP_CIPHER *EVP_des_ede_cbc(void) { return &evp_des_ede_cbc; }

static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out,
                              const uint8_t *in, size_t in_len) {
  if (in_len < ctx->cipher->block_size) {
    return 1;
  }
  in_len -= ctx->cipher->block_size;

  DES_EDE_KEY *dat = (DES_EDE_KEY *)ctx->cipher_data;
  for (size_t i = 0; i <= in_len; i += ctx->cipher->block_size) {
    DES_ecb3_encrypt_ex(in + i, out + i, &dat->ks.ks[0], &dat->ks.ks[1],
                        &dat->ks.ks[2], ctx->encrypt);
  }
  return 1;
}

static const EVP_CIPHER evp_des_ede = {
    /*nid=*/NID_des_ede_ecb,
    /*block_size=*/8,
    /*key_len=*/16,
    /*iv_len=*/0,
    /*ctx_size=*/sizeof(DES_EDE_KEY),
    /*flags=*/EVP_CIPH_ECB_MODE,
    /*init=*/des_ede_init_key,
    /*cipher=*/des_ede_ecb_cipher,
    /*cleanup=*/nullptr,
    /*ctrl=*/nullptr,
};

const EVP_CIPHER *EVP_des_ede(void) { return &evp_des_ede; }

static const EVP_CIPHER evp_des_ede3 = {
    /*nid=*/NID_des_ede3_ecb,
    /*block_size=*/8,
    /*key_len=*/24,
    /*iv_len=*/0,
    /*ctx_size=*/sizeof(DES_EDE_KEY),
    /*flags=*/EVP_CIPH_ECB_MODE,
    /*init=*/des_ede3_init_key,
    /*cipher=*/des_ede_ecb_cipher,
    /*cleanup=*/nullptr,
    /*ctrl=*/nullptr,
};

const EVP_CIPHER *EVP_des_ede3(void) { return &evp_des_ede3; }

const EVP_CIPHER *EVP_des_ede3_ecb(void) { return EVP_des_ede3(); }
