2 * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved.
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
11 #include <openssl/crypto.h>
12 #include "crypto/modes.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);
75 void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
76 size_t len, const void *key,
77 unsigned char ivec[16], block128_f block)
81 size_t t[16 / sizeof(size_t)];
88 #if !defined(OPENSSL_SMALL_FOOTPRINT)
90 const unsigned char *iv = ivec;
92 if (STRICT_ALIGNMENT &&
93 ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
95 (*block) (in, out, key);
96 for (n = 0; n < 16; ++n)
103 } else if (16 % sizeof(size_t) == 0) { /* always true */
105 size_t_aX *out_t = (size_t_aX *)out;
106 size_t_aX *iv_t = (size_t_aX *)iv;
108 (*block) (in, out, key);
109 for (n = 0; n < 16 / sizeof(size_t); n++)
117 memcpy(ivec, iv, 16);
119 if (STRICT_ALIGNMENT &&
120 ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
123 (*block) (in, tmp.c, key);
124 for (n = 0; n < 16; ++n) {
126 out[n] = tmp.c[n] ^ ivec[n];
133 } else if (16 % sizeof(size_t) == 0) { /* always true */
136 size_t_aX *out_t = (size_t_aX *)out;
137 size_t_aX *ivec_t = (size_t_aX *)ivec;
138 const size_t_aX *in_t = (const size_t_aX *)in;
140 (*block) (in, tmp.c, key);
141 for (n = 0; n < 16 / sizeof(size_t); n++) {
143 out_t[n] = tmp.t[n] ^ ivec_t[n];
155 (*block) (in, tmp.c, key);
156 for (n = 0; n < 16 && n < len; ++n) {
158 out[n] = tmp.c[n] ^ ivec[n];