2 * Copyright 2008-2016 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_lcl.h"
14 #if !defined(STRICT_ALIGNMENT) && !defined(PEDANTIC)
15 # define STRICT_ALIGNMENT 0
18 void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
19 size_t len, const void *key,
20 unsigned char ivec[16], block128_f block)
23 const unsigned char *iv = ivec;
25 #if !defined(OPENSSL_SMALL_FOOTPRINT)
26 if (STRICT_ALIGNMENT &&
27 ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
29 for (n = 0; n < 16; ++n)
30 out[n] = in[n] ^ iv[n];
31 (*block) (out, out, key);
39 for (n = 0; n < 16; n += sizeof(size_t))
40 *(size_t *)(out + n) =
41 *(size_t *)(in + n) ^ *(size_t *)(iv + n);
42 (*block) (out, out, key);
51 for (n = 0; n < 16 && n < len; ++n)
52 out[n] = in[n] ^ iv[n];
55 (*block) (out, out, key);
66 void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
67 size_t len, const void *key,
68 unsigned char ivec[16], block128_f block)
72 size_t t[16 / sizeof(size_t)];
76 #if !defined(OPENSSL_SMALL_FOOTPRINT)
78 const unsigned char *iv = ivec;
80 if (STRICT_ALIGNMENT &&
81 ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
83 (*block) (in, out, key);
84 for (n = 0; n < 16; ++n)
91 } else if (16 % sizeof(size_t) == 0) { /* always true */
93 size_t *out_t = (size_t *)out, *iv_t = (size_t *)iv;
95 (*block) (in, out, key);
96 for (n = 0; n < 16 / sizeof(size_t); n++)
104 memcpy(ivec, iv, 16);
106 if (STRICT_ALIGNMENT &&
107 ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
110 (*block) (in, tmp.c, key);
111 for (n = 0; n < 16; ++n) {
113 out[n] = tmp.c[n] ^ ivec[n];
120 } else if (16 % sizeof(size_t) == 0) { /* always true */
122 size_t c, *out_t = (size_t *)out, *ivec_t = (size_t *)ivec;
123 const size_t *in_t = (const size_t *)in;
125 (*block) (in, tmp.c, key);
126 for (n = 0; n < 16 / sizeof(size_t); n++) {
128 out_t[n] = tmp.t[n] ^ ivec_t[n];
140 (*block) (in, tmp.c, key);
141 for (n = 0; n < 16 && n < len; ++n) {
143 out[n] = tmp.c[n] ^ ivec[n];