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