Home | History | Annotate | Line # | Download | only in ciphers
      1 /*
      2  * Copyright 2019-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 #include "prov/ciphercommon.h"
     11 
     12 /*-
     13  * The generic cipher functions for cipher modes cbc, ecb, ofb, cfb and ctr.
     14  * Used if there is no special hardware implementations.
     15  */
     16 int ossl_cipher_hw_generic_cbc(PROV_CIPHER_CTX *dat, unsigned char *out,
     17     const unsigned char *in, size_t len)
     18 {
     19     if (dat->stream.cbc)
     20         (*dat->stream.cbc)(in, out, len, dat->ks, dat->iv, dat->enc);
     21     else if (dat->enc)
     22         CRYPTO_cbc128_encrypt(in, out, len, dat->ks, dat->iv, dat->block);
     23     else
     24         CRYPTO_cbc128_decrypt(in, out, len, dat->ks, dat->iv, dat->block);
     25 
     26     return 1;
     27 }
     28 
     29 int ossl_cipher_hw_generic_ecb(PROV_CIPHER_CTX *dat, unsigned char *out,
     30     const unsigned char *in, size_t len)
     31 {
     32     size_t i, bl = dat->blocksize;
     33 
     34     if (len < bl)
     35         return 1;
     36 
     37     if (dat->stream.ecb) {
     38         (*dat->stream.ecb)(in, out, len, dat->ks, dat->enc);
     39     } else {
     40         for (i = 0, len -= bl; i <= len; i += bl)
     41             (*dat->block)(in + i, out + i, dat->ks);
     42     }
     43 
     44     return 1;
     45 }
     46 
     47 int ossl_cipher_hw_generic_ofb128(PROV_CIPHER_CTX *dat, unsigned char *out,
     48     const unsigned char *in, size_t len)
     49 {
     50     int num = dat->num;
     51 
     52     CRYPTO_ofb128_encrypt(in, out, len, dat->ks, dat->iv, &num, dat->block);
     53     dat->num = num;
     54 
     55     return 1;
     56 }
     57 
     58 int ossl_cipher_hw_generic_cfb128(PROV_CIPHER_CTX *dat, unsigned char *out,
     59     const unsigned char *in, size_t len)
     60 {
     61     int num = dat->num;
     62 
     63     CRYPTO_cfb128_encrypt(in, out, len, dat->ks, dat->iv, &num, dat->enc,
     64         dat->block);
     65     dat->num = num;
     66 
     67     return 1;
     68 }
     69 
     70 int ossl_cipher_hw_generic_cfb8(PROV_CIPHER_CTX *dat, unsigned char *out,
     71     const unsigned char *in, size_t len)
     72 {
     73     int num = dat->num;
     74 
     75     CRYPTO_cfb128_8_encrypt(in, out, len, dat->ks, dat->iv, &num, dat->enc,
     76         dat->block);
     77     dat->num = num;
     78 
     79     return 1;
     80 }
     81 
     82 int ossl_cipher_hw_generic_cfb1(PROV_CIPHER_CTX *dat, unsigned char *out,
     83     const unsigned char *in, size_t len)
     84 {
     85     int num = dat->num;
     86 
     87     if (dat->use_bits) {
     88         CRYPTO_cfb128_1_encrypt(in, out, len, dat->ks, dat->iv, &num,
     89             dat->enc, dat->block);
     90         dat->num = num;
     91         return 1;
     92     }
     93 
     94     while (len >= MAXBITCHUNK) {
     95         CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, dat->ks,
     96             dat->iv, &num, dat->enc, dat->block);
     97         len -= MAXBITCHUNK;
     98         out += MAXBITCHUNK;
     99         in += MAXBITCHUNK;
    100     }
    101     if (len)
    102         CRYPTO_cfb128_1_encrypt(in, out, len * 8, dat->ks, dat->iv, &num,
    103             dat->enc, dat->block);
    104 
    105     dat->num = num;
    106 
    107     return 1;
    108 }
    109 
    110 int ossl_cipher_hw_generic_ctr(PROV_CIPHER_CTX *dat, unsigned char *out,
    111     const unsigned char *in, size_t len)
    112 {
    113     unsigned int num = dat->num;
    114 
    115     if (dat->stream.ctr)
    116         CRYPTO_ctr128_encrypt_ctr32(in, out, len, dat->ks, dat->iv, dat->buf,
    117             &num, dat->stream.ctr);
    118     else
    119         CRYPTO_ctr128_encrypt(in, out, len, dat->ks, dat->iv, dat->buf,
    120             &num, dat->block);
    121     dat->num = num;
    122 
    123     return 1;
    124 }
    125 
    126 /*-
    127  * The chunked cipher functions for cipher modes cbc, ecb, ofb, cfb and ctr.
    128  * Used if there is no special hardware implementations.
    129  */
    130 
    131 int ossl_cipher_hw_chunked_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out,
    132     const unsigned char *in, size_t inl)
    133 {
    134     while (inl >= MAXCHUNK) {
    135         ossl_cipher_hw_generic_cbc(ctx, out, in, MAXCHUNK);
    136         inl -= MAXCHUNK;
    137         in += MAXCHUNK;
    138         out += MAXCHUNK;
    139     }
    140     if (inl > 0)
    141         ossl_cipher_hw_generic_cbc(ctx, out, in, inl);
    142     return 1;
    143 }
    144 
    145 int ossl_cipher_hw_chunked_cfb8(PROV_CIPHER_CTX *ctx, unsigned char *out,
    146     const unsigned char *in, size_t inl)
    147 {
    148     size_t chunk = MAXCHUNK;
    149 
    150     if (inl < chunk)
    151         chunk = inl;
    152     while (inl > 0 && inl >= chunk) {
    153         ossl_cipher_hw_generic_cfb8(ctx, out, in, inl);
    154         inl -= chunk;
    155         in += chunk;
    156         out += chunk;
    157         if (inl < chunk)
    158             chunk = inl;
    159     }
    160     return 1;
    161 }
    162 
    163 int ossl_cipher_hw_chunked_cfb128(PROV_CIPHER_CTX *ctx, unsigned char *out,
    164     const unsigned char *in, size_t inl)
    165 {
    166     size_t chunk = MAXCHUNK;
    167 
    168     if (inl < chunk)
    169         chunk = inl;
    170     while (inl > 0 && inl >= chunk) {
    171         ossl_cipher_hw_generic_cfb128(ctx, out, in, inl);
    172         inl -= chunk;
    173         in += chunk;
    174         out += chunk;
    175         if (inl < chunk)
    176             chunk = inl;
    177     }
    178     return 1;
    179 }
    180 
    181 int ossl_cipher_hw_chunked_ofb128(PROV_CIPHER_CTX *ctx, unsigned char *out,
    182     const unsigned char *in, size_t inl)
    183 {
    184     while (inl >= MAXCHUNK) {
    185         ossl_cipher_hw_generic_ofb128(ctx, out, in, MAXCHUNK);
    186         inl -= MAXCHUNK;
    187         in += MAXCHUNK;
    188         out += MAXCHUNK;
    189     }
    190     if (inl > 0)
    191         ossl_cipher_hw_generic_ofb128(ctx, out, in, inl);
    192     return 1;
    193 }
    194