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 : des_t4_cbc_decrypt;
     32             return 1;
     33         }
     34     }
     35 #endif
     36     DES_set_key_unchecked(deskey, ks);
     37     return 1;
     38 }
     39 
     40 static void cipher_hw_des_copyctx(PROV_CIPHER_CTX *dst,
     41     const PROV_CIPHER_CTX *src)
     42 {
     43     PROV_DES_CTX *sctx = (PROV_DES_CTX *)src;
     44     PROV_DES_CTX *dctx = (PROV_DES_CTX *)dst;
     45 
     46     *dctx = *sctx;
     47     dst->ks = &dctx->dks.ks;
     48 }
     49 
     50 static int cipher_hw_des_ecb_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
     51     const unsigned char *in, size_t len)
     52 {
     53     size_t i, bl = ctx->blocksize;
     54     DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
     55 
     56     if (len < bl)
     57         return 1;
     58     for (i = 0, len -= bl; i <= len; i += bl)
     59         DES_ecb_encrypt((const_DES_cblock *)(in + i),
     60             (const_DES_cblock *)(out + i), key, ctx->enc);
     61     return 1;
     62 }
     63 
     64 static int cipher_hw_des_cbc_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
     65     const unsigned char *in, size_t len)
     66 {
     67     PROV_DES_CTX *dctx = (PROV_DES_CTX *)ctx;
     68     DES_key_schedule *key = &(dctx->dks.ks);
     69 
     70     if (dctx->dstream.cbc != NULL) {
     71         (*dctx->dstream.cbc)(in, out, len, key, ctx->iv);
     72         return 1;
     73     }
     74 
     75     while (len >= MAXCHUNK) {
     76         DES_ncbc_encrypt(in, out, MAXCHUNK, key, (DES_cblock *)ctx->iv,
     77             ctx->enc);
     78         len -= MAXCHUNK;
     79         in += MAXCHUNK;
     80         out += MAXCHUNK;
     81     }
     82     if (len > 0)
     83         DES_ncbc_encrypt(in, out, (long)len, key, (DES_cblock *)ctx->iv,
     84             ctx->enc);
     85     return 1;
     86 }
     87 
     88 static int cipher_hw_des_ofb64_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
     89     const unsigned char *in, size_t len)
     90 {
     91     int num = ctx->num;
     92     DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
     93 
     94     while (len >= MAXCHUNK) {
     95         DES_ofb64_encrypt(in, out, MAXCHUNK, key, (DES_cblock *)ctx->iv, &num);
     96         len -= MAXCHUNK;
     97         in += MAXCHUNK;
     98         out += MAXCHUNK;
     99     }
    100     if (len > 0) {
    101         DES_ofb64_encrypt(in, out, (long)len, key, (DES_cblock *)ctx->iv, &num);
    102     }
    103     ctx->num = num;
    104     return 1;
    105 }
    106 
    107 static int cipher_hw_des_cfb64_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
    108     const unsigned char *in, size_t len)
    109 {
    110     size_t chunk = MAXCHUNK;
    111     DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
    112     int num = ctx->num;
    113 
    114     if (len < chunk)
    115         chunk = len;
    116     while (len > 0 && len >= chunk) {
    117         DES_cfb64_encrypt(in, out, (long)chunk, key, (DES_cblock *)ctx->iv,
    118             &num, ctx->enc);
    119         len -= chunk;
    120         in += chunk;
    121         out += chunk;
    122         if (len < chunk)
    123             chunk = len;
    124     }
    125     ctx->num = num;
    126     return 1;
    127 }
    128 
    129 /*
    130  * Although we have a CFB-r implementation for DES, it doesn't pack the right
    131  * way, so wrap it here
    132  */
    133 static int cipher_hw_des_cfb1_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
    134     const unsigned char *in, size_t inl)
    135 {
    136     size_t n, chunk = MAXCHUNK / 8;
    137     DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
    138     unsigned char c[1];
    139     unsigned char d[1] = { 0 };
    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] = (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) | ((d[0] & 0x80) >> (unsigned int)(n % 8));
    149         }
    150         inl -= chunk;
    151         in += chunk;
    152         out += chunk;
    153         if (inl < chunk)
    154             chunk = inl;
    155     }
    156 
    157     return 1;
    158 }
    159 
    160 static int cipher_hw_des_cfb8_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
    161     const unsigned char *in, size_t inl)
    162 {
    163     DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
    164 
    165     while (inl >= MAXCHUNK) {
    166         DES_cfb_encrypt(in, out, 8, (long)MAXCHUNK, key,
    167             (DES_cblock *)ctx->iv, ctx->enc);
    168         inl -= MAXCHUNK;
    169         in += MAXCHUNK;
    170         out += MAXCHUNK;
    171     }
    172     if (inl > 0)
    173         DES_cfb_encrypt(in, out, 8, (long)inl, key,
    174             (DES_cblock *)ctx->iv, ctx->enc);
    175     return 1;
    176 }
    177 
    178 #define PROV_CIPHER_HW_des_mode(mode)                          \
    179     static const PROV_CIPHER_HW des_##mode = {                 \
    180         cipher_hw_des_initkey,                                 \
    181         cipher_hw_des_##mode##_cipher,                         \
    182         cipher_hw_des_copyctx                                  \
    183     };                                                         \
    184     const PROV_CIPHER_HW *ossl_prov_cipher_hw_des_##mode(void) \
    185     {                                                          \
    186         return &des_##mode;                                    \
    187     }
    188 
    189 PROV_CIPHER_HW_des_mode(ecb)
    190     PROV_CIPHER_HW_des_mode(cbc)
    191         PROV_CIPHER_HW_des_mode(ofb64)
    192             PROV_CIPHER_HW_des_mode(cfb64)
    193                 PROV_CIPHER_HW_des_mode(cfb1)
    194                     PROV_CIPHER_HW_des_mode(cfb8)
    195