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