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