1 /* 2 * Copyright 2020-2022 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 /* 11 * Helper functions for 128 bit CBC CTS ciphers (Currently AES and Camellia). 12 * 13 * The function dispatch tables are embedded into cipher_aes.c 14 * and cipher_camellia.c using cipher_aes_cts.inc and cipher_camellia_cts.inc 15 */ 16 17 /* 18 * Refer to SP800-38A-Addendum 19 * 20 * Ciphertext stealing encrypts plaintext using a block cipher, without padding 21 * the message to a multiple of the block size, so the ciphertext is the same 22 * size as the plaintext. 23 * It does this by altering processing of the last two blocks of the message. 24 * The processing of all but the last two blocks is unchanged, but a portion of 25 * the second-last block's ciphertext is "stolen" to pad the last plaintext 26 * block. The padded final block is then encrypted as usual. 27 * The final ciphertext for the last two blocks, consists of the partial block 28 * (with the "stolen" portion omitted) plus the full final block, 29 * which are the same size as the original plaintext. 30 * Decryption requires decrypting the final block first, then restoring the 31 * stolen ciphertext to the partial block, which can then be decrypted as usual. 32 33 * AES_CBC_CTS has 3 variants: 34 * (1) CS1 The NIST variant. 35 * If the length is a multiple of the blocksize it is the same as CBC mode. 36 * otherwise it produces C1||C2||(C(n-1))*||Cn. 37 * Where C(n-1)* is a partial block. 38 * (2) CS2 39 * If the length is a multiple of the blocksize it is the same as CBC mode. 40 * otherwise it produces C1||C2||Cn||(C(n-1))*. 41 * Where C(n-1)* is a partial block. 42 * (3) CS3 The Kerberos5 variant. 43 * Produces C1||C2||Cn||(C(n-1))* regardless of the length. 44 * If the length is a multiple of the blocksize it looks similar to CBC mode 45 * with the last 2 blocks swapped. 46 * Otherwise it is the same as CS2. 47 */ 48 49 #include <openssl/core_names.h> 50 #include "prov/ciphercommon.h" 51 #include "internal/nelem.h" 52 #include "cipher_cts.h" 53 54 /* The value assigned to 0 is the default */ 55 #define CTS_CS1 0 56 #define CTS_CS2 1 57 #define CTS_CS3 2 58 59 #define CTS_BLOCK_SIZE 16 60 61 typedef union { 62 size_t align; 63 unsigned char c[CTS_BLOCK_SIZE]; 64 } aligned_16bytes; 65 66 typedef struct cts_mode_name2id_st { 67 unsigned int id; 68 const char *name; 69 } CTS_MODE_NAME2ID; 70 71 static CTS_MODE_NAME2ID cts_modes[] = 72 { 73 { CTS_CS1, OSSL_CIPHER_CTS_MODE_CS1 }, 74 { CTS_CS2, OSSL_CIPHER_CTS_MODE_CS2 }, 75 { CTS_CS3, OSSL_CIPHER_CTS_MODE_CS3 }, 76 }; 77 78 const char *ossl_cipher_cbc_cts_mode_id2name(unsigned int id) 79 { 80 size_t i; 81 82 for (i = 0; i < OSSL_NELEM(cts_modes); ++i) { 83 if (cts_modes[i].id == id) 84 return cts_modes[i].name; 85 } 86 return NULL; 87 } 88 89 int ossl_cipher_cbc_cts_mode_name2id(const char *name) 90 { 91 size_t i; 92 93 for (i = 0; i < OSSL_NELEM(cts_modes); ++i) { 94 if (OPENSSL_strcasecmp(name, cts_modes[i].name) == 0) 95 return (int)cts_modes[i].id; 96 } 97 return -1; 98 } 99 100 static size_t cts128_cs1_encrypt(PROV_CIPHER_CTX *ctx, const unsigned char *in, 101 unsigned char *out, size_t len) 102 { 103 aligned_16bytes tmp_in; 104 size_t residue; 105 106 residue = len % CTS_BLOCK_SIZE; 107 len -= residue; 108 if (!ctx->hw->cipher(ctx, out, in, len)) 109 return 0; 110 111 if (residue == 0) 112 return len; 113 114 in += len; 115 out += len; 116 117 memset(tmp_in.c, 0, sizeof(tmp_in)); 118 memcpy(tmp_in.c, in, residue); 119 if (!ctx->hw->cipher(ctx, out - CTS_BLOCK_SIZE + residue, tmp_in.c, 120 CTS_BLOCK_SIZE)) 121 return 0; 122 return len + residue; 123 } 124 125 static void do_xor(const unsigned char *in1, const unsigned char *in2, 126 size_t len, unsigned char *out) 127 { 128 size_t i; 129 130 for (i = 0; i < len; ++i) 131 out[i] = in1[i] ^ in2[i]; 132 } 133 134 static size_t cts128_cs1_decrypt(PROV_CIPHER_CTX *ctx, const unsigned char *in, 135 unsigned char *out, size_t len) 136 { 137 aligned_16bytes mid_iv, ct_mid, cn, pt_last; 138 size_t residue; 139 140 residue = len % CTS_BLOCK_SIZE; 141 if (residue == 0) { 142 /* If there are no partial blocks then it is the same as CBC mode */ 143 if (!ctx->hw->cipher(ctx, out, in, len)) 144 return 0; 145 return len; 146 } 147 /* Process blocks at the start - but leave the last 2 blocks */ 148 len -= CTS_BLOCK_SIZE + residue; 149 if (len > 0) { 150 if (!ctx->hw->cipher(ctx, out, in, len)) 151 return 0; 152 in += len; 153 out += len; 154 } 155 /* Save the iv that will be used by the second last block */ 156 memcpy(mid_iv.c, ctx->iv, CTS_BLOCK_SIZE); 157 /* Save the C(n) block */ 158 memcpy(cn.c, in + residue, CTS_BLOCK_SIZE); 159 160 /* Decrypt the last block first using an iv of zero */ 161 memset(ctx->iv, 0, CTS_BLOCK_SIZE); 162 if (!ctx->hw->cipher(ctx, pt_last.c, in + residue, CTS_BLOCK_SIZE)) 163 return 0; 164 165 /* 166 * Rebuild the ciphertext of the second last block as a combination of 167 * the decrypted last block + replace the start with the ciphertext bytes 168 * of the partial second last block. 169 */ 170 memcpy(ct_mid.c, in, residue); 171 memcpy(ct_mid.c + residue, pt_last.c + residue, CTS_BLOCK_SIZE - residue); 172 /* 173 * Restore the last partial ciphertext block. 174 * Now that we have the cipher text of the second last block, apply 175 * that to the partial plaintext end block. We have already decrypted the 176 * block using an IV of zero. For decryption the IV is just XORed after 177 * doing an Cipher CBC block - so just XOR in the cipher text. 178 */ 179 do_xor(ct_mid.c, pt_last.c, residue, out + CTS_BLOCK_SIZE); 180 181 /* Restore the iv needed by the second last block */ 182 memcpy(ctx->iv, mid_iv.c, CTS_BLOCK_SIZE); 183 184 /* 185 * Decrypt the second last plaintext block now that we have rebuilt the 186 * ciphertext. 187 */ 188 if (!ctx->hw->cipher(ctx, out, ct_mid.c, CTS_BLOCK_SIZE)) 189 return 0; 190 191 /* The returned iv is the C(n) block */ 192 memcpy(ctx->iv, cn.c, CTS_BLOCK_SIZE); 193 return len + CTS_BLOCK_SIZE + residue; 194 } 195 196 static size_t cts128_cs3_encrypt(PROV_CIPHER_CTX *ctx, const unsigned char *in, 197 unsigned char *out, size_t len) 198 { 199 aligned_16bytes tmp_in; 200 size_t residue; 201 202 if (len < CTS_BLOCK_SIZE) /* CS3 requires at least one block */ 203 return 0; 204 205 /* If we only have one block then just process the aligned block */ 206 if (len == CTS_BLOCK_SIZE) 207 return ctx->hw->cipher(ctx, out, in, len) ? len : 0; 208 209 residue = len % CTS_BLOCK_SIZE; 210 if (residue == 0) 211 residue = CTS_BLOCK_SIZE; 212 len -= residue; 213 214 if (!ctx->hw->cipher(ctx, out, in, len)) 215 return 0; 216 217 in += len; 218 out += len; 219 220 memset(tmp_in.c, 0, sizeof(tmp_in)); 221 memcpy(tmp_in.c, in, residue); 222 memcpy(out, out - CTS_BLOCK_SIZE, residue); 223 if (!ctx->hw->cipher(ctx, out - CTS_BLOCK_SIZE, tmp_in.c, CTS_BLOCK_SIZE)) 224 return 0; 225 return len + residue; 226 } 227 228 /* 229 * Note: 230 * The cipher text (in) is of the form C(0), C(1), ., C(n), C(n-1)* where 231 * C(n) is a full block and C(n-1)* can be a partial block 232 * (but could be a full block). 233 * This means that the output plaintext (out) needs to swap the plaintext of 234 * the last two decoded ciphertext blocks. 235 */ 236 static size_t cts128_cs3_decrypt(PROV_CIPHER_CTX *ctx, const unsigned char *in, 237 unsigned char *out, size_t len) 238 { 239 aligned_16bytes mid_iv, ct_mid, cn, pt_last; 240 size_t residue; 241 242 if (len < CTS_BLOCK_SIZE) /* CS3 requires at least one block */ 243 return 0; 244 245 /* If we only have one block then just process the aligned block */ 246 if (len == CTS_BLOCK_SIZE) 247 return ctx->hw->cipher(ctx, out, in, len) ? len : 0; 248 249 /* Process blocks at the start - but leave the last 2 blocks */ 250 residue = len % CTS_BLOCK_SIZE; 251 if (residue == 0) 252 residue = CTS_BLOCK_SIZE; 253 len -= CTS_BLOCK_SIZE + residue; 254 255 if (len > 0) { 256 if (!ctx->hw->cipher(ctx, out, in, len)) 257 return 0; 258 in += len; 259 out += len; 260 } 261 /* Save the iv that will be used by the second last block */ 262 memcpy(mid_iv.c, ctx->iv, CTS_BLOCK_SIZE); 263 /* Save the C(n) block : For CS3 it is C(1)||...||C(n-2)||C(n)||C(n-1)* */ 264 memcpy(cn.c, in, CTS_BLOCK_SIZE); 265 266 /* Decrypt the C(n) block first using an iv of zero */ 267 memset(ctx->iv, 0, CTS_BLOCK_SIZE); 268 if (!ctx->hw->cipher(ctx, pt_last.c, in, CTS_BLOCK_SIZE)) 269 return 0; 270 271 /* 272 * Rebuild the ciphertext of C(n-1) as a combination of 273 * the decrypted C(n) block + replace the start with the ciphertext bytes 274 * of the partial last block. 275 */ 276 memcpy(ct_mid.c, in + CTS_BLOCK_SIZE, residue); 277 if (residue != CTS_BLOCK_SIZE) 278 memcpy(ct_mid.c + residue, pt_last.c + residue, CTS_BLOCK_SIZE - residue); 279 /* 280 * Restore the last partial ciphertext block. 281 * Now that we have the cipher text of the second last block, apply 282 * that to the partial plaintext end block. We have already decrypted the 283 * block using an IV of zero. For decryption the IV is just XORed after 284 * doing an AES block - so just XOR in the ciphertext. 285 */ 286 do_xor(ct_mid.c, pt_last.c, residue, out + CTS_BLOCK_SIZE); 287 288 /* Restore the iv needed by the second last block */ 289 memcpy(ctx->iv, mid_iv.c, CTS_BLOCK_SIZE); 290 /* 291 * Decrypt the second last plaintext block now that we have rebuilt the 292 * ciphertext. 293 */ 294 if (!ctx->hw->cipher(ctx, out, ct_mid.c, CTS_BLOCK_SIZE)) 295 return 0; 296 297 /* The returned iv is the C(n) block */ 298 memcpy(ctx->iv, cn.c, CTS_BLOCK_SIZE); 299 return len + CTS_BLOCK_SIZE + residue; 300 } 301 302 static size_t cts128_cs2_encrypt(PROV_CIPHER_CTX *ctx, const unsigned char *in, 303 unsigned char *out, size_t len) 304 { 305 if (len % CTS_BLOCK_SIZE == 0) { 306 /* If there are no partial blocks then it is the same as CBC mode */ 307 if (!ctx->hw->cipher(ctx, out, in, len)) 308 return 0; 309 return len; 310 } 311 /* For partial blocks CS2 is equivalent to CS3 */ 312 return cts128_cs3_encrypt(ctx, in, out, len); 313 } 314 315 static size_t cts128_cs2_decrypt(PROV_CIPHER_CTX *ctx, const unsigned char *in, 316 unsigned char *out, size_t len) 317 { 318 if (len % CTS_BLOCK_SIZE == 0) { 319 /* If there are no partial blocks then it is the same as CBC mode */ 320 if (!ctx->hw->cipher(ctx, out, in, len)) 321 return 0; 322 return len; 323 } 324 /* For partial blocks CS2 is equivalent to CS3 */ 325 return cts128_cs3_decrypt(ctx, in, out, len); 326 } 327 328 int ossl_cipher_cbc_cts_block_update(void *vctx, unsigned char *out, size_t *outl, 329 size_t outsize, const unsigned char *in, 330 size_t inl) 331 { 332 PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; 333 size_t sz = 0; 334 335 if (inl < CTS_BLOCK_SIZE) /* There must be at least one block for CTS mode */ 336 return 0; 337 if (outsize < inl) 338 return 0; 339 if (out == NULL) { 340 *outl = inl; 341 return 1; 342 } 343 344 /* 345 * Return an error if the update is called multiple times, only one shot 346 * is supported. 347 */ 348 if (ctx->updated == 1) 349 return 0; 350 351 if (ctx->enc) { 352 if (ctx->cts_mode == CTS_CS1) 353 sz = cts128_cs1_encrypt(ctx, in, out, inl); 354 else if (ctx->cts_mode == CTS_CS2) 355 sz = cts128_cs2_encrypt(ctx, in, out, inl); 356 else if (ctx->cts_mode == CTS_CS3) 357 sz = cts128_cs3_encrypt(ctx, in, out, inl); 358 } else { 359 if (ctx->cts_mode == CTS_CS1) 360 sz = cts128_cs1_decrypt(ctx, in, out, inl); 361 else if (ctx->cts_mode == CTS_CS2) 362 sz = cts128_cs2_decrypt(ctx, in, out, inl); 363 else if (ctx->cts_mode == CTS_CS3) 364 sz = cts128_cs3_decrypt(ctx, in, out, inl); 365 } 366 if (sz == 0) 367 return 0; 368 ctx->updated = 1; /* Stop multiple updates being allowed */ 369 *outl = sz; 370 return 1; 371 } 372 373 int ossl_cipher_cbc_cts_block_final(void *vctx, unsigned char *out, size_t *outl, 374 size_t outsize) 375 { 376 *outl = 0; 377 return 1; 378 } 379