| Viewing file:  cipher_des_hw.c (6.2 KB)      -rw-r--r-- Select action/file-type:
 
  (+) |  (+) |  (+) | Code (+) | Session (+) |  (+) | SDB (+) |  (+) |  (+) |  (+) |  (+) |  (+) | 
 
/** Copyright 1995-2021 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 "prov/ciphercommon.h"
 #include "cipher_des.h"
 
 static int cipher_hw_des_initkey(PROV_CIPHER_CTX *ctx,
 const unsigned char *key, size_t keylen)
 {
 PROV_DES_CTX *dctx = (PROV_DES_CTX *)ctx;
 DES_cblock *deskey = (DES_cblock *)key;
 DES_key_schedule *ks = &dctx->dks.ks;
 
 dctx->dstream.cbc = NULL;
 #if defined(SPARC_DES_CAPABLE)
 if (SPARC_DES_CAPABLE) {
 if (ctx->mode == EVP_CIPH_CBC_MODE) {
 des_t4_key_expand(&deskey[0], ks);
 dctx->dstream.cbc = ctx->enc ? des_t4_cbc_encrypt :
 des_t4_cbc_decrypt;
 return 1;
 }
 }
 #endif
 DES_set_key_unchecked(deskey, ks);
 return 1;
 }
 
 static void cipher_hw_des_copyctx(PROV_CIPHER_CTX *dst,
 const PROV_CIPHER_CTX *src)
 {
 PROV_DES_CTX *sctx = (PROV_DES_CTX *)src;
 PROV_DES_CTX *dctx = (PROV_DES_CTX *)dst;
 
 *dctx = *sctx;
 dst->ks = &dctx->dks.ks;
 }
 
 static int cipher_hw_des_ecb_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
 const unsigned char *in, size_t len)
 {
 size_t i, bl = ctx->blocksize;
 DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
 
 if (len < bl)
 return 1;
 for (i = 0, len -= bl; i <= len; i += bl)
 DES_ecb_encrypt((const_DES_cblock *)(in + i),
 (const_DES_cblock *)(out + i), key, ctx->enc);
 return 1;
 }
 
 static int cipher_hw_des_cbc_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
 const unsigned char *in, size_t len)
 {
 PROV_DES_CTX *dctx = (PROV_DES_CTX *)ctx;
 DES_key_schedule *key = &(dctx->dks.ks);
 
 if (dctx->dstream.cbc != NULL) {
 (*dctx->dstream.cbc) (in, out, len, key, ctx->iv);
 return 1;
 }
 
 while (len >= MAXCHUNK) {
 DES_ncbc_encrypt(in, out, MAXCHUNK, key, (DES_cblock *)ctx->iv,
 ctx->enc);
 len -= MAXCHUNK;
 in += MAXCHUNK;
 out += MAXCHUNK;
 }
 if (len > 0)
 DES_ncbc_encrypt(in, out, (long)len, key, (DES_cblock *)ctx->iv,
 ctx->enc);
 return 1;
 }
 
 static int cipher_hw_des_ofb64_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
 const unsigned char *in, size_t len)
 {
 int num = ctx->num;
 DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
 
 while (len >= MAXCHUNK) {
 DES_ofb64_encrypt(in, out, MAXCHUNK, key, (DES_cblock *)ctx->iv, &num);
 len -= MAXCHUNK;
 in += MAXCHUNK;
 out += MAXCHUNK;
 }
 if (len > 0) {
 DES_ofb64_encrypt(in, out, (long)len, key, (DES_cblock *)ctx->iv, &num);
 }
 ctx->num = num;
 return 1;
 }
 
 static int cipher_hw_des_cfb64_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
 const unsigned char *in, size_t len)
 {
 size_t chunk = MAXCHUNK;
 DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
 int num = ctx->num;
 
 if (len < chunk)
 chunk = len;
 while (len > 0 && len >= chunk) {
 DES_cfb64_encrypt(in, out, (long)chunk, key, (DES_cblock *)ctx->iv,
 &num, ctx->enc);
 len -= chunk;
 in += chunk;
 out += chunk;
 if (len < chunk)
 chunk = len;
 }
 ctx->num = num;
 return 1;
 }
 
 /*
 * Although we have a CFB-r implementation for DES, it doesn't pack the right
 * way, so wrap it here
 */
 static int cipher_hw_des_cfb1_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
 const unsigned char *in, size_t inl)
 {
 size_t n, chunk = MAXCHUNK / 8;
 DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
 unsigned char c[1];
 unsigned char d[1] = { 0 };
 
 if (inl < chunk)
 chunk = inl;
 
 while (inl && inl >= chunk) {
 for (n = 0; n < chunk * 8; ++n) {
 c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
 DES_cfb_encrypt(c, d, 1, 1, key, (DES_cblock *)ctx->iv, ctx->enc);
 out[n / 8] =
 (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) |
 ((d[0] & 0x80) >> (unsigned int)(n % 8));
 }
 inl -= chunk;
 in += chunk;
 out += chunk;
 if (inl < chunk)
 chunk = inl;
 }
 
 return 1;
 }
 
 static int cipher_hw_des_cfb8_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
 const unsigned char *in, size_t inl)
 {
 DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
 
 while (inl >= MAXCHUNK) {
 DES_cfb_encrypt(in, out, 8, (long)MAXCHUNK, key,
 (DES_cblock *)ctx->iv, ctx->enc);
 inl -= MAXCHUNK;
 in += MAXCHUNK;
 out += MAXCHUNK;
 }
 if (inl > 0)
 DES_cfb_encrypt(in, out, 8, (long)inl, key,
 (DES_cblock *)ctx->iv, ctx->enc);
 return 1;
 }
 
 #define PROV_CIPHER_HW_des_mode(mode)                                          \
 static const PROV_CIPHER_HW des_##mode = {                                     \
 cipher_hw_des_initkey,                                                     \
 cipher_hw_des_##mode##_cipher,                                             \
 cipher_hw_des_copyctx                                                      \
 };                                                                             \
 const PROV_CIPHER_HW *ossl_prov_cipher_hw_des_##mode(void)                     \
 {                                                                              \
 return &des_##mode;                                                        \
 }
 
 PROV_CIPHER_HW_des_mode(ecb)
 PROV_CIPHER_HW_des_mode(cbc)
 PROV_CIPHER_HW_des_mode(ofb64)
 PROV_CIPHER_HW_des_mode(cfb64)
 PROV_CIPHER_HW_des_mode(cfb1)
 PROV_CIPHER_HW_des_mode(cfb8)
 
 |