Home | History | Annotate | Line # | Download | only in ciphers
      1 /*
      2  * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  * this file except in compliance with the License.  You can obtain a copy
      6  * in the file LICENSE in the source distribution or at
      7  * https://www.openssl.org/source/license.html
      8  */
      9 
     10 /*
     11  * DES low level APIs are deprecated for public use, but still ok for internal
     12  * use.
     13  */
     14 #include "internal/deprecated.h"
     15 
     16 #include "prov/ciphercommon.h"
     17 #include "cipher_des.h"
     18 
     19 static int cipher_hw_des_initkey(PROV_CIPHER_CTX *ctx,
     20                                  const unsigned char *key, size_t keylen)
     21 {
     22     PROV_DES_CTX *dctx = (PROV_DES_CTX *)ctx;
     23     DES_cblock *deskey = (DES_cblock *)key;
     24     DES_key_schedule *ks = &dctx->dks.ks;
     25 
     26     dctx->dstream.cbc = NULL;
     27 #if defined(SPARC_DES_CAPABLE)
     28     if (SPARC_DES_CAPABLE) {
     29         if (ctx->mode == EVP_CIPH_CBC_MODE) {
     30             des_t4_key_expand(&deskey[0], ks);
     31             dctx->dstream.cbc = ctx->enc ? des_t4_cbc_encrypt :
     32                                            des_t4_cbc_decrypt;
     33             return 1;
     34         }
     35     }
     36 #endif
     37     DES_set_key_unchecked(deskey, ks);
     38     return 1;
     39 }
     40 
     41 static void cipher_hw_des_copyctx(PROV_CIPHER_CTX *dst,
     42                                   const PROV_CIPHER_CTX *src)
     43 {
     44     PROV_DES_CTX *sctx = (PROV_DES_CTX *)src;
     45     PROV_DES_CTX *dctx = (PROV_DES_CTX *)dst;
     46 
     47     *dctx = *sctx;
     48     dst->ks = &dctx->dks.ks;
     49 }
     50 
     51 static int cipher_hw_des_ecb_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
     52                                     const unsigned char *in, size_t len)
     53 {
     54     size_t i, bl = ctx->blocksize;
     55     DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
     56 
     57     if (len < bl)
     58         return 1;
     59     for (i = 0, len -= bl; i <= len; i += bl)
     60         DES_ecb_encrypt((const_DES_cblock *)(in + i),
     61                         (const_DES_cblock *)(out + i), key, ctx->enc);
     62     return 1;
     63 }
     64 
     65 static int cipher_hw_des_cbc_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
     66                                     const unsigned char *in, size_t len)
     67 {
     68     PROV_DES_CTX *dctx = (PROV_DES_CTX *)ctx;
     69     DES_key_schedule *key = &(dctx->dks.ks);
     70 
     71     if (dctx->dstream.cbc != NULL) {
     72         (*dctx->dstream.cbc) (in, out, len, key, ctx->iv);
     73         return 1;
     74     }
     75 
     76     while (len >= MAXCHUNK) {
     77         DES_ncbc_encrypt(in, out, MAXCHUNK, key, (DES_cblock *)ctx->iv,
     78                          ctx->enc);
     79         len -= MAXCHUNK;
     80         in += MAXCHUNK;
     81         out += MAXCHUNK;
     82     }
     83     if (len > 0)
     84         DES_ncbc_encrypt(in, out, (long)len, key, (DES_cblock *)ctx->iv,
     85                          ctx->enc);
     86     return 1;
     87 }
     88 
     89 static int cipher_hw_des_ofb64_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
     90                                       const unsigned char *in, size_t len)
     91 {
     92     int num = ctx->num;
     93     DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
     94 
     95     while (len >= MAXCHUNK) {
     96         DES_ofb64_encrypt(in, out, MAXCHUNK, key, (DES_cblock *)ctx->iv, &num);
     97         len -= MAXCHUNK;
     98         in += MAXCHUNK;
     99         out += MAXCHUNK;
    100     }
    101     if (len > 0) {
    102         DES_ofb64_encrypt(in, out, (long)len, key, (DES_cblock *)ctx->iv, &num);
    103     }
    104     ctx->num = num;
    105     return 1;
    106 }
    107 
    108 static int cipher_hw_des_cfb64_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
    109                                       const unsigned char *in, size_t len)
    110 {
    111     size_t chunk = MAXCHUNK;
    112     DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
    113     int num = ctx->num;
    114 
    115     if (len < chunk)
    116         chunk = len;
    117     while (len > 0 && len >= chunk) {
    118         DES_cfb64_encrypt(in, out, (long)chunk, key, (DES_cblock *)ctx->iv,
    119                           &num, ctx->enc);
    120         len -= chunk;
    121         in += chunk;
    122         out += chunk;
    123         if (len < chunk)
    124             chunk = len;
    125     }
    126     ctx->num = num;
    127     return 1;
    128 }
    129 
    130 /*
    131  * Although we have a CFB-r implementation for DES, it doesn't pack the right
    132  * way, so wrap it here
    133  */
    134 static int cipher_hw_des_cfb1_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
    135                                      const unsigned char *in, size_t inl)
    136 {
    137     size_t n, chunk = MAXCHUNK / 8;
    138     DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
    139     unsigned char c[1], d[1];
    140 
    141     if (inl < chunk)
    142         chunk = inl;
    143 
    144     while (inl && inl >= chunk) {
    145         for (n = 0; n < chunk * 8; ++n) {
    146             c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
    147             DES_cfb_encrypt(c, d, 1, 1, key, (DES_cblock *)ctx->iv, ctx->enc);
    148             out[n / 8] =
    149                 (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) |
    150                 ((d[0] & 0x80) >> (unsigned int)(n % 8));
    151         }
    152         inl -= chunk;
    153         in += chunk;
    154         out += chunk;
    155         if (inl < chunk)
    156             chunk = inl;
    157     }
    158 
    159     return 1;
    160 }
    161 
    162 static int cipher_hw_des_cfb8_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
    163                                      const unsigned char *in, size_t inl)
    164 {
    165     DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
    166 
    167     while (inl >= MAXCHUNK) {
    168         DES_cfb_encrypt(in, out, 8, (long)MAXCHUNK, key,
    169                         (DES_cblock *)ctx->iv, ctx->enc);
    170         inl -= MAXCHUNK;
    171         in += MAXCHUNK;
    172         out += MAXCHUNK;
    173     }
    174     if (inl > 0)
    175         DES_cfb_encrypt(in, out, 8, (long)inl, key,
    176                         (DES_cblock *)ctx->iv, ctx->enc);
    177     return 1;
    178 }
    179 
    180 #define PROV_CIPHER_HW_des_mode(mode)                                          \
    181 static const PROV_CIPHER_HW des_##mode = {                                     \
    182     cipher_hw_des_initkey,                                                     \
    183     cipher_hw_des_##mode##_cipher,                                             \
    184     cipher_hw_des_copyctx                                                      \
    185 };                                                                             \
    186 const PROV_CIPHER_HW *ossl_prov_cipher_hw_des_##mode(void)                     \
    187 {                                                                              \
    188     return &des_##mode;                                                        \
    189 }
    190 
    191 PROV_CIPHER_HW_des_mode(ecb)
    192 PROV_CIPHER_HW_des_mode(cbc)
    193 PROV_CIPHER_HW_des_mode(ofb64)
    194 PROV_CIPHER_HW_des_mode(cfb64)
    195 PROV_CIPHER_HW_des_mode(cfb1)
    196 PROV_CIPHER_HW_des_mode(cfb8)
    197