/*
 * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

/*
 * DES low level APIs are deprecated for public use, but still ok for internal
 * use.
 */
#include "internal/deprecated.h"

#include <openssl/des.h>
#include "cipher_tdes_default.h"

/*
 * Note the PROV_TDES_CTX has been used for the DESX cipher, just to reduce
 * code size.
 */
#define ks1 tks.ks[0]
#define ks2 tks.ks[1].ks[0].cblock
#define ks3 tks.ks[2].ks[0].cblock

static int cipher_hw_desx_cbc_initkey(PROV_CIPHER_CTX *ctx,
                                      const unsigned char *key, size_t keylen)
{
    PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx;
    DES_cblock *deskey = (DES_cblock *)key;

    DES_set_key_unchecked(deskey, &tctx->ks1);
    memcpy(&tctx->ks2, &key[8], 8);
    memcpy(&tctx->ks3, &key[16], 8);

    return 1;
}

static void cipher_hw_desx_copyctx(PROV_CIPHER_CTX *dst,
                                   const PROV_CIPHER_CTX *src)
{
    PROV_TDES_CTX *sctx = (PROV_TDES_CTX *)src;
    PROV_TDES_CTX *dctx = (PROV_TDES_CTX *)dst;

    *dctx = *sctx;
    dst->ks = &dctx->tks.ks;
}

static int cipher_hw_desx_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out,
                              const unsigned char *in, size_t inl)
{
    PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx;

    while (inl >= MAXCHUNK) {
        DES_xcbc_encrypt(in, out, (long)MAXCHUNK, &tctx->ks1,
                         (DES_cblock *)ctx->iv, &tctx->ks2, &tctx->ks3,
                         ctx->enc);
        inl -= MAXCHUNK;
        in += MAXCHUNK;
        out += MAXCHUNK;
    }
    if (inl > 0)
        DES_xcbc_encrypt(in, out, (long)inl, &tctx->ks1,
                         (DES_cblock *)ctx->iv, &tctx->ks2, &tctx->ks3,
                         ctx->enc);
    return 1;
}

static const PROV_CIPHER_HW desx_cbc =
{
    cipher_hw_desx_cbc_initkey,
    cipher_hw_desx_cbc,
    cipher_hw_desx_copyctx
};

const PROV_CIPHER_HW *ossl_prov_cipher_hw_tdes_desx_cbc(void)
{
    return &desx_cbc;
}
