1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ====================================================================
2221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the documentation and/or other materials provided with the
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    distribution.
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    software must display the following acknowledgment:
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    endorse or promote products derived from this software without
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    prior written permission. For written permission, please contact
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    openssl-core@openssl.org.
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL"
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    nor may "OpenSSL" appear in their names without prior written
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    permission of the OpenSSL Project.
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    acknowledgment:
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE.
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ====================================================================
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
51221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include "modes.h"
52221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <string.h>
53221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
54221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifndef MODES_DEBUG
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# ifndef NDEBUG
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#  define NDEBUG
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# endif
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <assert.h>
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
61221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#define STRICT_ALIGNMENT
62221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#if defined(__i386) || defined(__i386__) || \
63221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    defined(__x86_64) || defined(__x86_64__) || \
64221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
65221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    defined(__s390__) || defined(__s390x__)
66221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#  undef STRICT_ALIGNMENT
67221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
68221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
69221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* The input and output encrypted as though 128bit ofb mode is being
70221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * used.  The extra state information to record how much of the
71221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * 128bit block we have used is contained in *num;
72221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom */
73221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromvoid CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out,
74221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			size_t len, const void *key,
75221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			unsigned char ivec[16], int *num,
76221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			block128_f block)
77221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{
78221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	unsigned int n;
79221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	size_t l=0;
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
81221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	assert(in && out && key && ivec && num);
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
83221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	n = *num;
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
85221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#if !defined(OPENSSL_SMALL_FOOTPRINT)
86221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (16%sizeof(size_t) == 0) do { /* always true actually */
87221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		while (n && len) {
88221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			*(out++) = *(in++) ^ ivec[n];
89221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			--len;
90221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			n = (n+1) % 16;
91221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
92221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#if defined(STRICT_ALIGNMENT)
93221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
94221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			break;
95221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
96221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		while (len>=16) {
97221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			(*block)(ivec, ivec, key);
983d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom			for (; n<16; n+=sizeof(size_t))
99221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				*(size_t*)(out+n) =
100221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				*(size_t*)(in+n) ^ *(size_t*)(ivec+n);
101221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			len -= 16;
102221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			out += 16;
103221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			in  += 16;
1043d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom			n = 0;
105221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
106221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (len) {
107221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			(*block)(ivec, ivec, key);
108221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			while (len--) {
109221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				out[n] = in[n] ^ ivec[n];
110221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				++n;
111221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
112221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
113221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		*num = n;
114221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return;
115221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	} while(0);
116221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* the rest would be commonly eliminated by x86* compiler */
117221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
118221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	while (l<len) {
119221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (n==0) {
120221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			(*block)(ivec, ivec, key);
121221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
122221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		out[l] = in[l] ^ ivec[n];
123221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		++l;
124221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		n = (n+1) % 16;
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
127221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	*num=n;
128221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
129