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