123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- /*
- * 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], d[1];
- 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)
|