1 /* 2 * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. 3 * 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 8 */ 9 10 #include <openssl/crypto.h> 11 #include "modes_local.h" 12 #include <string.h> 13 14 #if defined(__GNUC__) && !defined(STRICT_ALIGNMENT) 15 typedef size_t size_t_aX __attribute((__aligned__(1))); 16 #else 17 typedef size_t size_t_aX; 18 #endif 19 20 /* 21 * The input and output encrypted as though 128bit ofb mode is being used. 22 * The extra state information to record how much of the 128bit block we have 23 * used is contained in *num; 24 */ 25 void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out, 26 size_t len, const void *key, 27 unsigned char ivec[16], int *num, block128_f block) 28 { 29 unsigned int n; 30 size_t l = 0; 31 32 n = *num; 33 34 #if !defined(OPENSSL_SMALL_FOOTPRINT) 35 if (16 % sizeof(size_t) == 0) { /* always true actually */ 36 do { 37 while (n && len) { 38 *(out++) = *(in++) ^ ivec[n]; 39 --len; 40 n = (n + 1) % 16; 41 } 42 # if defined(STRICT_ALIGNMENT) 43 if (((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 44 0) 45 break; 46 # endif 47 while (len >= 16) { 48 (*block) (ivec, ivec, key); 49 for (; n < 16; n += sizeof(size_t)) 50 *(size_t_aX *)(out + n) = 51 *(size_t_aX *)(in + n) 52 ^ *(size_t_aX *)(ivec + n); 53 len -= 16; 54 out += 16; 55 in += 16; 56 n = 0; 57 } 58 if (len) { 59 (*block) (ivec, ivec, key); 60 while (len--) { 61 out[n] = in[n] ^ ivec[n]; 62 ++n; 63 } 64 } 65 *num = n; 66 return; 67 } while (0); 68 } 69 /* the rest would be commonly eliminated by x86* compiler */ 70 #endif 71 while (l < len) { 72 if (n == 0) { 73 (*block) (ivec, ivec, key); 74 } 75 out[l] = in[l] ^ ivec[n]; 76 ++l; 77 n = (n + 1) % 16; 78 } 79 80 *num = n; 81 } 82