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