2 * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (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
10 #include <openssl/crypto.h>
11 #include "modes_local.h"
14 #if !defined(STRICT_ALIGNMENT) && !defined(PEDANTIC)
15 # define STRICT_ALIGNMENT 0
18 #if defined(__GNUC__) && !STRICT_ALIGNMENT
19 typedef size_t size_t_aX __attribute((__aligned__(1)));
21 typedef size_t size_t_aX;
24 void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
25 size_t len, const void *key,
26 unsigned char ivec[16], block128_f block)
29 const unsigned char *iv = ivec;
34 #if !defined(OPENSSL_SMALL_FOOTPRINT)
35 if (STRICT_ALIGNMENT &&
36 ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
38 for (n = 0; n < 16; ++n)
39 out[n] = in[n] ^ iv[n];
40 (*block) (out, out, key);
48 for (n = 0; n < 16; n += sizeof(size_t))
49 *(size_t_aX *)(out + n) =
50 *(size_t_aX *)(in + n) ^ *(size_t_aX *)(iv + n);
51 (*block) (out, out, key);
60 for (n = 0; n < 16 && n < len; ++n)
61 out[n] = in[n] ^ iv[n];
64 (*block) (out, out, key);
76 void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
77 size_t len, const void *key,
78 unsigned char ivec[16], block128_f block)
82 size_t t[16 / sizeof(size_t)];
89 #if !defined(OPENSSL_SMALL_FOOTPRINT)
91 const unsigned char *iv = ivec;
93 if (STRICT_ALIGNMENT &&
94 ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
96 (*block) (in, out, key);
97 for (n = 0; n < 16; ++n)
104 } else if (16 % sizeof(size_t) == 0) { /* always true */
106 size_t_aX *out_t = (size_t_aX *)out;
107 size_t_aX *iv_t = (size_t_aX *)iv;
109 (*block) (in, out, key);
110 for (n = 0; n < 16 / sizeof(size_t); n++)
119 memcpy(ivec, iv, 16);
121 if (STRICT_ALIGNMENT &&
122 ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
125 (*block) (in, tmp.c, key);
126 for (n = 0; n < 16; ++n) {
128 out[n] = tmp.c[n] ^ ivec[n];
135 } else if (16 % sizeof(size_t) == 0) { /* always true */
138 size_t_aX *out_t = (size_t_aX *)out;
139 size_t_aX *ivec_t = (size_t_aX *)ivec;
140 const size_t_aX *in_t = (const size_t_aX *)in;
142 (*block) (in, tmp.c, key);
143 for (n = 0; n < 16 / sizeof(size_t); n++) {
145 out_t[n] = tmp.t[n] ^ ivec_t[n];
157 (*block) (in, tmp.c, key);
158 for (n = 0; n < 16 && n < len; ++n) {
160 out[n] = tmp.c[n] ^ ivec[n];