summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/modes
diff options
context:
space:
mode:
authordjm <>2010-10-01 22:54:21 +0000
committerdjm <>2010-10-01 22:54:21 +0000
commit829fd51d4f8dde4a7f3bf54754f3c1d1a502f5e2 (patch)
treee03b9f1bd051e844b971936729e9df549a209130 /src/lib/libcrypto/modes
parente6b755d2a53d3cac7a344dfdd6bf7c951cac754c (diff)
downloadopenbsd-829fd51d4f8dde4a7f3bf54754f3c1d1a502f5e2.tar.gz
openbsd-829fd51d4f8dde4a7f3bf54754f3c1d1a502f5e2.tar.bz2
openbsd-829fd51d4f8dde4a7f3bf54754f3c1d1a502f5e2.zip
import OpenSSL-1.0.0a
Diffstat (limited to 'src/lib/libcrypto/modes')
-rw-r--r--src/lib/libcrypto/modes/cbc128.c206
-rw-r--r--src/lib/libcrypto/modes/cfb128.c249
-rw-r--r--src/lib/libcrypto/modes/ctr128.c184
-rw-r--r--src/lib/libcrypto/modes/cts128.c259
-rw-r--r--src/lib/libcrypto/modes/modes.h59
-rw-r--r--src/lib/libcrypto/modes/ofb128.c128
6 files changed, 1085 insertions, 0 deletions
diff --git a/src/lib/libcrypto/modes/cbc128.c b/src/lib/libcrypto/modes/cbc128.c
new file mode 100644
index 0000000000..8f8bd563b9
--- /dev/null
+++ b/src/lib/libcrypto/modes/cbc128.c
@@ -0,0 +1,206 @@
1/* ====================================================================
2 * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 */
50
51#include "modes.h"
52#include <string.h>
53
54#ifndef MODES_DEBUG
55# ifndef NDEBUG
56# define NDEBUG
57# endif
58#endif
59#include <assert.h>
60
61#define STRICT_ALIGNMENT 1
62#if defined(__i386) || defined(__i386__) || \
63 defined(__x86_64) || defined(__x86_64__) || \
64 defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
65 defined(__s390__) || defined(__s390x__)
66# undef STRICT_ALIGNMENT
67# define STRICT_ALIGNMENT 0
68#endif
69
70void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
71 size_t len, const void *key,
72 unsigned char ivec[16], block128_f block)
73{
74 size_t n;
75 const unsigned char *iv = ivec;
76
77 assert(in && out && key && ivec);
78
79#if !defined(OPENSSL_SMALL_FOOTPRINT)
80 if (STRICT_ALIGNMENT &&
81 ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) {
82 while (len>=16) {
83 for(n=0; n<16; ++n)
84 out[n] = in[n] ^ iv[n];
85 (*block)(out, out, key);
86 iv = out;
87 len -= 16;
88 in += 16;
89 out += 16;
90 }
91 } else {
92 while (len>=16) {
93 for(n=0; n<16; n+=sizeof(size_t))
94 *(size_t*)(out+n) =
95 *(size_t*)(in+n) ^ *(size_t*)(iv+n);
96 (*block)(out, out, key);
97 iv = out;
98 len -= 16;
99 in += 16;
100 out += 16;
101 }
102 }
103#endif
104 while (len) {
105 for(n=0; n<16 && n<len; ++n)
106 out[n] = in[n] ^ iv[n];
107 for(; n<16; ++n)
108 out[n] = iv[n];
109 (*block)(out, out, key);
110 iv = out;
111 if (len<=16) break;
112 len -= 16;
113 in += 16;
114 out += 16;
115 }
116 memcpy(ivec,iv,16);
117}
118
119void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
120 size_t len, const void *key,
121 unsigned char ivec[16], block128_f block)
122{
123 size_t n;
124 union { size_t align; unsigned char c[16]; } tmp;
125
126 assert(in && out && key && ivec);
127
128#if !defined(OPENSSL_SMALL_FOOTPRINT)
129 if (in != out) {
130 const unsigned char *iv = ivec;
131
132 if (STRICT_ALIGNMENT &&
133 ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) {
134 while (len>=16) {
135 (*block)(in, out, key);
136 for(n=0; n<16; ++n)
137 out[n] ^= iv[n];
138 iv = in;
139 len -= 16;
140 in += 16;
141 out += 16;
142 }
143 }
144 else {
145 while (len>=16) {
146 (*block)(in, out, key);
147 for(n=0; n<16; n+=sizeof(size_t))
148 *(size_t *)(out+n) ^= *(size_t *)(iv+n);
149 iv = in;
150 len -= 16;
151 in += 16;
152 out += 16;
153 }
154 }
155 memcpy(ivec,iv,16);
156 } else {
157 if (STRICT_ALIGNMENT &&
158 ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) {
159 unsigned char c;
160 while (len>=16) {
161 (*block)(in, tmp.c, key);
162 for(n=0; n<16; ++n) {
163 c = in[n];
164 out[n] = tmp.c[n] ^ ivec[n];
165 ivec[n] = c;
166 }
167 len -= 16;
168 in += 16;
169 out += 16;
170 }
171 }
172 else {
173 size_t c;
174 while (len>=16) {
175 (*block)(in, tmp.c, key);
176 for(n=0; n<16; n+=sizeof(size_t)) {
177 c = *(size_t *)(in+n);
178 *(size_t *)(out+n) =
179 *(size_t *)(tmp.c+n) ^ *(size_t *)(ivec+n);
180 *(size_t *)(ivec+n) = c;
181 }
182 len -= 16;
183 in += 16;
184 out += 16;
185 }
186 }
187 }
188#endif
189 while (len) {
190 unsigned char c;
191 (*block)(in, tmp.c, key);
192 for(n=0; n<16 && n<len; ++n) {
193 c = in[n];
194 out[n] = tmp.c[n] ^ ivec[n];
195 ivec[n] = c;
196 }
197 if (len<=16) {
198 for (; n<16; ++n)
199 ivec[n] = in[n];
200 break;
201 }
202 len -= 16;
203 in += 16;
204 out += 16;
205 }
206}
diff --git a/src/lib/libcrypto/modes/cfb128.c b/src/lib/libcrypto/modes/cfb128.c
new file mode 100644
index 0000000000..e5938c6137
--- /dev/null
+++ b/src/lib/libcrypto/modes/cfb128.c
@@ -0,0 +1,249 @@
1/* ====================================================================
2 * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 */
50
51#include "modes.h"
52#include <string.h>
53
54#ifndef MODES_DEBUG
55# ifndef NDEBUG
56# define NDEBUG
57# endif
58#endif
59#include <assert.h>
60
61#define STRICT_ALIGNMENT
62#if defined(__i386) || defined(__i386__) || \
63 defined(__x86_64) || defined(__x86_64__) || \
64 defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
65 defined(__s390__) || defined(__s390x__)
66# undef STRICT_ALIGNMENT
67#endif
68
69/* The input and output encrypted as though 128bit cfb mode is being
70 * used. The extra state information to record how much of the
71 * 128bit block we have used is contained in *num;
72 */
73void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out,
74 size_t len, const void *key,
75 unsigned char ivec[16], int *num,
76 int enc, block128_f block)
77{
78 unsigned int n;
79 size_t l = 0;
80
81 assert(in && out && key && ivec && num);
82
83 n = *num;
84
85 if (enc) {
86#if !defined(OPENSSL_SMALL_FOOTPRINT)
87 if (16%sizeof(size_t) == 0) do { /* always true actually */
88 while (n && len) {
89 *(out++) = ivec[n] ^= *(in++);
90 --len;
91 n = (n+1) % 16;
92 }
93#if defined(STRICT_ALIGNMENT)
94 if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
95 break;
96#endif
97 while (len>=16) {
98 (*block)(ivec, ivec, key);
99 for (; n<16; n+=sizeof(size_t)) {
100 *(size_t*)(out+n) =
101 *(size_t*)(ivec+n) ^= *(size_t*)(in+n);
102 }
103 len -= 16;
104 out += 16;
105 in += 16;
106 n = 0;
107 }
108 if (len) {
109 (*block)(ivec, ivec, key);
110 while (len--) {
111 out[n] = ivec[n] ^= in[n];
112 ++n;
113 }
114 }
115 *num = n;
116 return;
117 } while (0);
118 /* the rest would be commonly eliminated by x86* compiler */
119#endif
120 while (l<len) {
121 if (n == 0) {
122 (*block)(ivec, ivec, key);
123 }
124 out[l] = ivec[n] ^= in[l];
125 ++l;
126 n = (n+1) % 16;
127 }
128 *num = n;
129 } else {
130#if !defined(OPENSSL_SMALL_FOOTPRINT)
131 if (16%sizeof(size_t) == 0) do { /* always true actually */
132 while (n && len) {
133 unsigned char c;
134 *(out++) = ivec[n] ^ (c = *(in++)); ivec[n] = c;
135 --len;
136 n = (n+1) % 16;
137 }
138#if defined(STRICT_ALIGNMENT)
139 if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
140 break;
141#endif
142 while (len>=16) {
143 (*block)(ivec, ivec, key);
144 for (; n<16; n+=sizeof(size_t)) {
145 size_t t = *(size_t*)(in+n);
146 *(size_t*)(out+n) = *(size_t*)(ivec+n) ^ t;
147 *(size_t*)(ivec+n) = t;
148 }
149 len -= 16;
150 out += 16;
151 in += 16;
152 n = 0;
153 }
154 if (len) {
155 (*block)(ivec, ivec, key);
156 while (len--) {
157 unsigned char c;
158 out[n] = ivec[n] ^ (c = in[n]); ivec[n] = c;
159 ++n;
160 }
161 }
162 *num = n;
163 return;
164 } while (0);
165 /* the rest would be commonly eliminated by x86* compiler */
166#endif
167 while (l<len) {
168 unsigned char c;
169 if (n == 0) {
170 (*block)(ivec, ivec, key);
171 }
172 out[l] = ivec[n] ^ (c = in[l]); ivec[n] = c;
173 ++l;
174 n = (n+1) % 16;
175 }
176 *num=n;
177 }
178}
179
180/* This expects a single block of size nbits for both in and out. Note that
181 it corrupts any extra bits in the last byte of out */
182static void cfbr_encrypt_block(const unsigned char *in,unsigned char *out,
183 int nbits,const void *key,
184 unsigned char ivec[16],int enc,
185 block128_f block)
186{
187 int n,rem,num;
188 unsigned char ovec[16*2 + 1]; /* +1 because we dererefence (but don't use) one byte off the end */
189
190 if (nbits<=0 || nbits>128) return;
191
192 /* fill in the first half of the new IV with the current IV */
193 memcpy(ovec,ivec,16);
194 /* construct the new IV */
195 (*block)(ivec,ivec,key);
196 num = (nbits+7)/8;
197 if (enc) /* encrypt the input */
198 for(n=0 ; n < num ; ++n)
199 out[n] = (ovec[16+n] = in[n] ^ ivec[n]);
200 else /* decrypt the input */
201 for(n=0 ; n < num ; ++n)
202 out[n] = (ovec[16+n] = in[n]) ^ ivec[n];
203 /* shift ovec left... */
204 rem = nbits%8;
205 num = nbits/8;
206 if(rem==0)
207 memcpy(ivec,ovec+num,16);
208 else
209 for(n=0 ; n < 16 ; ++n)
210 ivec[n] = ovec[n+num]<<rem | ovec[n+num+1]>>(8-rem);
211
212 /* it is not necessary to cleanse ovec, since the IV is not secret */
213}
214
215/* N.B. This expects the input to be packed, MS bit first */
216void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out,
217 size_t bits, const void *key,
218 unsigned char ivec[16], int *num,
219 int enc, block128_f block)
220{
221 size_t n;
222 unsigned char c[1],d[1];
223
224 assert(in && out && key && ivec && num);
225 assert(*num == 0);
226
227 for(n=0 ; n<bits ; ++n)
228 {
229 c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0;
230 cfbr_encrypt_block(c,d,1,key,ivec,enc,block);
231 out[n/8]=(out[n/8]&~(1 << (unsigned int)(7-n%8))) |
232 ((d[0]&0x80) >> (unsigned int)(n%8));
233 }
234}
235
236void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out,
237 size_t length, const void *key,
238 unsigned char ivec[16], int *num,
239 int enc, block128_f block)
240{
241 size_t n;
242
243 assert(in && out && key && ivec && num);
244 assert(*num == 0);
245
246 for(n=0 ; n<length ; ++n)
247 cfbr_encrypt_block(&in[n],&out[n],8,key,ivec,enc,block);
248}
249
diff --git a/src/lib/libcrypto/modes/ctr128.c b/src/lib/libcrypto/modes/ctr128.c
new file mode 100644
index 0000000000..932037f551
--- /dev/null
+++ b/src/lib/libcrypto/modes/ctr128.c
@@ -0,0 +1,184 @@
1/* ====================================================================
2 * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 */
50
51#include "modes.h"
52#include <string.h>
53
54#ifndef MODES_DEBUG
55# ifndef NDEBUG
56# define NDEBUG
57# endif
58#endif
59#include <assert.h>
60
61typedef unsigned int u32;
62typedef unsigned char u8;
63
64#define STRICT_ALIGNMENT
65#if defined(__i386) || defined(__i386__) || \
66 defined(__x86_64) || defined(__x86_64__) || \
67 defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
68 defined(__s390__) || defined(__s390x__)
69# undef STRICT_ALIGNMENT
70#endif
71
72/* NOTE: the IV/counter CTR mode is big-endian. The code itself
73 * is endian-neutral. */
74
75/* increment counter (128-bit int) by 1 */
76static void ctr128_inc(unsigned char *counter) {
77 u32 n=16;
78 u8 c;
79
80 do {
81 --n;
82 c = counter[n];
83 ++c;
84 counter[n] = c;
85 if (c) return;
86 } while (n);
87}
88
89#if !defined(OPENSSL_SMALL_FOOTPRINT)
90static void ctr128_inc_aligned(unsigned char *counter) {
91 size_t *data,c,n;
92 const union { long one; char little; } is_endian = {1};
93
94 if (is_endian.little) {
95 ctr128_inc(counter);
96 return;
97 }
98
99 data = (size_t *)counter;
100 n = 16/sizeof(size_t);
101 do {
102 --n;
103 c = data[n];
104 ++c;
105 data[n] = c;
106 if (c) return;
107 } while (n);
108}
109#endif
110
111/* The input encrypted as though 128bit counter mode is being
112 * used. The extra state information to record how much of the
113 * 128bit block we have used is contained in *num, and the
114 * encrypted counter is kept in ecount_buf. Both *num and
115 * ecount_buf must be initialised with zeros before the first
116 * call to CRYPTO_ctr128_encrypt().
117 *
118 * This algorithm assumes that the counter is in the x lower bits
119 * of the IV (ivec), and that the application has full control over
120 * overflow and the rest of the IV. This implementation takes NO
121 * responsability for checking that the counter doesn't overflow
122 * into the rest of the IV when incremented.
123 */
124void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
125 size_t len, const void *key,
126 unsigned char ivec[16], unsigned char ecount_buf[16],
127 unsigned int *num, block128_f block)
128{
129 unsigned int n;
130 size_t l=0;
131
132 assert(in && out && key && ecount_buf && num);
133 assert(*num < 16);
134
135 n = *num;
136
137#if !defined(OPENSSL_SMALL_FOOTPRINT)
138 if (16%sizeof(size_t) == 0) do { /* always true actually */
139 while (n && len) {
140 *(out++) = *(in++) ^ ecount_buf[n];
141 --len;
142 n = (n+1) % 16;
143 }
144
145#if defined(STRICT_ALIGNMENT)
146 if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
147 break;
148#endif
149 while (len>=16) {
150 (*block)(ivec, ecount_buf, key);
151 ctr128_inc_aligned(ivec);
152 for (; n<16; n+=sizeof(size_t))
153 *(size_t *)(out+n) =
154 *(size_t *)(in+n) ^ *(size_t *)(ecount_buf+n);
155 len -= 16;
156 out += 16;
157 in += 16;
158 n = 0;
159 }
160 if (len) {
161 (*block)(ivec, ecount_buf, key);
162 ctr128_inc_aligned(ivec);
163 while (len--) {
164 out[n] = in[n] ^ ecount_buf[n];
165 ++n;
166 }
167 }
168 *num = n;
169 return;
170 } while(0);
171 /* the rest would be commonly eliminated by x86* compiler */
172#endif
173 while (l<len) {
174 if (n==0) {
175 (*block)(ivec, ecount_buf, key);
176 ctr128_inc(ivec);
177 }
178 out[l] = in[l] ^ ecount_buf[n];
179 ++l;
180 n = (n+1) % 16;
181 }
182
183 *num=n;
184}
diff --git a/src/lib/libcrypto/modes/cts128.c b/src/lib/libcrypto/modes/cts128.c
new file mode 100644
index 0000000000..e0430f9fdc
--- /dev/null
+++ b/src/lib/libcrypto/modes/cts128.c
@@ -0,0 +1,259 @@
1/* ====================================================================
2 * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
3 *
4 * Rights for redistribution and usage in source and binary
5 * forms are granted according to the OpenSSL license.
6 */
7
8#include "modes.h"
9#include <string.h>
10
11#ifndef MODES_DEBUG
12# ifndef NDEBUG
13# define NDEBUG
14# endif
15#endif
16#include <assert.h>
17
18/*
19 * Trouble with Ciphertext Stealing, CTS, mode is that there is no
20 * common official specification, but couple of cipher/application
21 * specific ones: RFC2040 and RFC3962. Then there is 'Proposal to
22 * Extend CBC Mode By "Ciphertext Stealing"' at NIST site, which
23 * deviates from mentioned RFCs. Most notably it allows input to be
24 * of block length and it doesn't flip the order of the last two
25 * blocks. CTS is being discussed even in ECB context, but it's not
26 * adopted for any known application. This implementation complies
27 * with mentioned RFCs and [as such] extends CBC mode.
28 */
29
30size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, unsigned char *out,
31 size_t len, const void *key,
32 unsigned char ivec[16], block128_f block)
33{ size_t residue, n;
34
35 assert (in && out && key && ivec);
36
37 if (len <= 16) return 0;
38
39 if ((residue=len%16) == 0) residue = 16;
40
41 len -= residue;
42
43 CRYPTO_cbc128_encrypt(in,out,len,key,ivec,block);
44
45 in += len;
46 out += len;
47
48 for (n=0; n<residue; ++n)
49 ivec[n] ^= in[n];
50 (*block)(ivec,ivec,key);
51 memcpy(out,out-16,residue);
52 memcpy(out-16,ivec,16);
53
54 return len+residue;
55}
56
57size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out,
58 size_t len, const void *key,
59 unsigned char ivec[16], cbc128_f cbc)
60{ size_t residue;
61 union { size_t align; unsigned char c[16]; } tmp;
62
63 assert (in && out && key && ivec);
64
65 if (len <= 16) return 0;
66
67 if ((residue=len%16) == 0) residue = 16;
68
69 len -= residue;
70
71 (*cbc)(in,out,len,key,ivec,1);
72
73 in += len;
74 out += len;
75
76#if defined(CBC_HANDLES_TRUNCATED_IO)
77 memcpy(tmp.c,out-16,16);
78 (*cbc)(in,out-16,residue,key,ivec,1);
79 memcpy(out,tmp.c,residue);
80#else
81 {
82 size_t n;
83 for (n=0; n<16; n+=sizeof(size_t))
84 *(size_t *)(tmp.c+n) = 0;
85 memcpy(tmp.c,in,residue);
86 }
87 memcpy(out,out-16,residue);
88 (*cbc)(tmp.c,out-16,16,key,ivec,1);
89#endif
90 return len+residue;
91}
92
93size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, unsigned char *out,
94 size_t len, const void *key,
95 unsigned char ivec[16], block128_f block)
96{ size_t residue, n;
97 union { size_t align; unsigned char c[32]; } tmp;
98
99 assert (in && out && key && ivec);
100
101 if (len<=16) return 0;
102
103 if ((residue=len%16) == 0) residue = 16;
104
105 len -= 16+residue;
106
107 if (len) {
108 CRYPTO_cbc128_decrypt(in,out,len,key,ivec,block);
109 in += len;
110 out += len;
111 }
112
113 (*block)(in,tmp.c+16,key);
114
115 for (n=0; n<16; n+=sizeof(size_t))
116 *(size_t *)(tmp.c+n) = *(size_t *)(tmp.c+16+n);
117 memcpy(tmp.c,in+16,residue);
118 (*block)(tmp.c,tmp.c,key);
119
120 for(n=0; n<16; ++n) {
121 unsigned char c = in[n];
122 out[n] = tmp.c[n] ^ ivec[n];
123 ivec[n] = c;
124 }
125 for(residue+=16; n<residue; ++n)
126 out[n] = tmp.c[n] ^ in[n];
127
128 return len+residue-16;
129}
130
131size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
132 size_t len, const void *key,
133 unsigned char ivec[16], cbc128_f cbc)
134{ size_t residue, n;
135 union { size_t align; unsigned char c[32]; } tmp;
136
137 assert (in && out && key && ivec);
138
139 if (len<=16) return 0;
140
141 if ((residue=len%16) == 0) residue = 16;
142
143 len -= 16+residue;
144
145 if (len) {
146 (*cbc)(in,out,len,key,ivec,0);
147 in += len;
148 out += len;
149 }
150
151 for (n=16; n<32; n+=sizeof(size_t))
152 *(size_t *)(tmp.c+n) = 0;
153 /* this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0] */
154 (*cbc)(in,tmp.c,16,key,tmp.c+16,0);
155
156 memcpy(tmp.c,in+16,residue);
157#if defined(CBC_HANDLES_TRUNCATED_IO)
158 (*cbc)(tmp.c,out,16+residue,key,ivec,0);
159#else
160 (*cbc)(tmp.c,tmp.c,32,key,ivec,0);
161 memcpy(out,tmp.c,16+residue);
162#endif
163 return len+residue;
164}
165
166#if defined(SELFTEST)
167#include <stdio.h>
168#include <openssl/aes.h>
169
170/* test vectors from RFC 3962 */
171static const unsigned char test_key[16] = "chicken teriyaki";
172static const unsigned char test_input[64] =
173 "I would like the" " General Gau's C"
174 "hicken, please, " "and wonton soup.";
175static const unsigned char test_iv[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
176
177static const unsigned char vector_17[17] =
178{0xc6,0x35,0x35,0x68,0xf2,0xbf,0x8c,0xb4, 0xd8,0xa5,0x80,0x36,0x2d,0xa7,0xff,0x7f,
179 0x97};
180static const unsigned char vector_31[31] =
181{0xfc,0x00,0x78,0x3e,0x0e,0xfd,0xb2,0xc1, 0xd4,0x45,0xd4,0xc8,0xef,0xf7,0xed,0x22,
182 0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5};
183static const unsigned char vector_32[32] =
184{0x39,0x31,0x25,0x23,0xa7,0x86,0x62,0xd5, 0xbe,0x7f,0xcb,0xcc,0x98,0xeb,0xf5,0xa8,
185 0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5,0x84};
186static const unsigned char vector_47[47] =
187{0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5,0x84,
188 0xb3,0xff,0xfd,0x94,0x0c,0x16,0xa1,0x8c, 0x1b,0x55,0x49,0xd2,0xf8,0x38,0x02,0x9e,
189 0x39,0x31,0x25,0x23,0xa7,0x86,0x62,0xd5, 0xbe,0x7f,0xcb,0xcc,0x98,0xeb,0xf5};
190static const unsigned char vector_48[48] =
191{0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5,0x84,
192 0x9d,0xad,0x8b,0xbb,0x96,0xc4,0xcd,0xc0, 0x3b,0xc1,0x03,0xe1,0xa1,0x94,0xbb,0xd8,
193 0x39,0x31,0x25,0x23,0xa7,0x86,0x62,0xd5, 0xbe,0x7f,0xcb,0xcc,0x98,0xeb,0xf5,0xa8};
194static const unsigned char vector_64[64] =
195{0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5,0x84,
196 0x39,0x31,0x25,0x23,0xa7,0x86,0x62,0xd5, 0xbe,0x7f,0xcb,0xcc,0x98,0xeb,0xf5,0xa8,
197 0x48,0x07,0xef,0xe8,0x36,0xee,0x89,0xa5, 0x26,0x73,0x0d,0xbc,0x2f,0x7b,0xc8,0x40,
198 0x9d,0xad,0x8b,0xbb,0x96,0xc4,0xcd,0xc0, 0x3b,0xc1,0x03,0xe1,0xa1,0x94,0xbb,0xd8};
199
200static AES_KEY encks, decks;
201
202void test_vector(const unsigned char *vector,size_t len)
203{ unsigned char cleartext[64];
204 unsigned char iv[sizeof(test_iv)];
205 unsigned char ciphertext[64];
206 size_t tail;
207
208 printf("vector_%d\n",len); fflush(stdout);
209
210 if ((tail=len%16) == 0) tail = 16;
211 tail += 16;
212
213 /* test block-based encryption */
214 memcpy(iv,test_iv,sizeof(test_iv));
215 CRYPTO_cts128_encrypt_block(test_input,ciphertext,len,&encks,iv,(block128_f)AES_encrypt);
216 if (memcmp(ciphertext,vector,len))
217 fprintf(stderr,"output_%d mismatch\n",len), exit(1);
218 if (memcmp(iv,vector+len-tail,sizeof(iv)))
219 fprintf(stderr,"iv_%d mismatch\n",len), exit(1);
220
221 /* test block-based decryption */
222 memcpy(iv,test_iv,sizeof(test_iv));
223 CRYPTO_cts128_decrypt_block(ciphertext,cleartext,len,&decks,iv,(block128_f)AES_decrypt);
224 if (memcmp(cleartext,test_input,len))
225 fprintf(stderr,"input_%d mismatch\n",len), exit(2);
226 if (memcmp(iv,vector+len-tail,sizeof(iv)))
227 fprintf(stderr,"iv_%d mismatch\n",len), exit(2);
228
229 /* test streamed encryption */
230 memcpy(iv,test_iv,sizeof(test_iv));
231 CRYPTO_cts128_encrypt(test_input,ciphertext,len,&encks,iv,(cbc128_f)AES_cbc_encrypt);
232 if (memcmp(ciphertext,vector,len))
233 fprintf(stderr,"output_%d mismatch\n",len), exit(3);
234 if (memcmp(iv,vector+len-tail,sizeof(iv)))
235 fprintf(stderr,"iv_%d mismatch\n",len), exit(3);
236
237 /* test streamed decryption */
238 memcpy(iv,test_iv,sizeof(test_iv));
239 CRYPTO_cts128_decrypt(ciphertext,cleartext,len,&decks,iv,(cbc128_f)AES_cbc_encrypt);
240 if (memcmp(cleartext,test_input,len))
241 fprintf(stderr,"input_%d mismatch\n",len), exit(4);
242 if (memcmp(iv,vector+len-tail,sizeof(iv)))
243 fprintf(stderr,"iv_%d mismatch\n",len), exit(4);
244}
245
246main()
247{
248 AES_set_encrypt_key(test_key,128,&encks);
249 AES_set_decrypt_key(test_key,128,&decks);
250
251 test_vector(vector_17,sizeof(vector_17));
252 test_vector(vector_31,sizeof(vector_31));
253 test_vector(vector_32,sizeof(vector_32));
254 test_vector(vector_47,sizeof(vector_47));
255 test_vector(vector_48,sizeof(vector_48));
256 test_vector(vector_64,sizeof(vector_64));
257 exit(0);
258}
259#endif
diff --git a/src/lib/libcrypto/modes/modes.h b/src/lib/libcrypto/modes/modes.h
new file mode 100644
index 0000000000..af8d97d795
--- /dev/null
+++ b/src/lib/libcrypto/modes/modes.h
@@ -0,0 +1,59 @@
1/* ====================================================================
2 * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
3 *
4 * Rights for redistribution and usage in source and binary
5 * forms are granted according to the OpenSSL license.
6 */
7
8#include <stddef.h>
9
10typedef void (*block128_f)(const unsigned char in[16],
11 unsigned char out[16],
12 const void *key);
13
14typedef void (*cbc128_f)(const unsigned char *in, unsigned char *out,
15 size_t len, const void *key,
16 unsigned char ivec[16], int enc);
17
18void 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);
21void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
22 size_t len, const void *key,
23 unsigned char ivec[16], block128_f block);
24
25void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
26 size_t len, const void *key,
27 unsigned char ivec[16], unsigned char ecount_buf[16],
28 unsigned int *num, block128_f block);
29
30void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out,
31 size_t len, const void *key,
32 unsigned char ivec[16], int *num,
33 block128_f block);
34
35void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out,
36 size_t len, const void *key,
37 unsigned char ivec[16], int *num,
38 int enc, block128_f block);
39void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out,
40 size_t length, const void *key,
41 unsigned char ivec[16], int *num,
42 int enc, block128_f block);
43void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out,
44 size_t bits, const void *key,
45 unsigned char ivec[16], int *num,
46 int enc, block128_f block);
47
48size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, unsigned char *out,
49 size_t len, const void *key,
50 unsigned char ivec[16], block128_f block);
51size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out,
52 size_t len, const void *key,
53 unsigned char ivec[16], cbc128_f cbc);
54size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, unsigned char *out,
55 size_t len, const void *key,
56 unsigned char ivec[16], block128_f block);
57size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
58 size_t len, const void *key,
59 unsigned char ivec[16], cbc128_f cbc);
diff --git a/src/lib/libcrypto/modes/ofb128.c b/src/lib/libcrypto/modes/ofb128.c
new file mode 100644
index 0000000000..c732e2ec58
--- /dev/null
+++ b/src/lib/libcrypto/modes/ofb128.c
@@ -0,0 +1,128 @@
1/* ====================================================================
2 * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 */
50
51#include "modes.h"
52#include <string.h>
53
54#ifndef MODES_DEBUG
55# ifndef NDEBUG
56# define NDEBUG
57# endif
58#endif
59#include <assert.h>
60
61#define STRICT_ALIGNMENT
62#if defined(__i386) || defined(__i386__) || \
63 defined(__x86_64) || defined(__x86_64__) || \
64 defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
65 defined(__s390__) || defined(__s390x__)
66# undef STRICT_ALIGNMENT
67#endif
68
69/* The input and output encrypted as though 128bit ofb mode is being
70 * used. The extra state information to record how much of the
71 * 128bit block we have used is contained in *num;
72 */
73void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out,
74 size_t len, const void *key,
75 unsigned char ivec[16], int *num,
76 block128_f block)
77{
78 unsigned int n;
79 size_t l=0;
80
81 assert(in && out && key && ivec && num);
82
83 n = *num;
84
85#if !defined(OPENSSL_SMALL_FOOTPRINT)
86 if (16%sizeof(size_t) == 0) do { /* always true actually */
87 while (n && len) {
88 *(out++) = *(in++) ^ ivec[n];
89 --len;
90 n = (n+1) % 16;
91 }
92#if defined(STRICT_ALIGNMENT)
93 if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
94 break;
95#endif
96 while (len>=16) {
97 (*block)(ivec, ivec, key);
98 for (; n<16; n+=sizeof(size_t))
99 *(size_t*)(out+n) =
100 *(size_t*)(in+n) ^ *(size_t*)(ivec+n);
101 len -= 16;
102 out += 16;
103 in += 16;
104 n = 0;
105 }
106 if (len) {
107 (*block)(ivec, ivec, key);
108 while (len--) {
109 out[n] = in[n] ^ ivec[n];
110 ++n;
111 }
112 }
113 *num = n;
114 return;
115 } while(0);
116 /* the rest would be commonly eliminated by x86* compiler */
117#endif
118 while (l<len) {
119 if (n==0) {
120 (*block)(ivec, ivec, key);
121 }
122 out[l] = in[l] ^ ivec[n];
123 ++l;
124 n = (n+1) % 16;
125 }
126
127 *num=n;
128}