comparison nss/lib/freebl/desblapi.c @ 0:1e5118fa0cb1

This is NSS with a Cmake Buildsyste To compile a static NSS library for Windows we've used the Chromium-NSS fork and added a Cmake buildsystem to compile it statically for Windows. See README.chromium for chromium changes and README.trustbridge for our modifications.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 28 Jul 2014 10:47:06 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1e5118fa0cb1
1 /*
2 * desblapi.c
3 *
4 * core source file for DES-150 library
5 * Implement DES Modes of Operation and Triple-DES.
6 * Adapt DES-150 to blapi API.
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
11
12 #ifdef FREEBL_NO_DEPEND
13 #include "stubs.h"
14 #endif
15
16 #include "des.h"
17 #include <stddef.h>
18 #include "secerr.h"
19
20 #if defined(NSS_X86_OR_X64)
21 /* Intel X86 CPUs do unaligned loads and stores without complaint. */
22 #define COPY8B(to, from, ptr) \
23 HALFPTR(to)[0] = HALFPTR(from)[0]; \
24 HALFPTR(to)[1] = HALFPTR(from)[1];
25 #elif defined(USE_MEMCPY)
26 #define COPY8B(to, from, ptr) memcpy(to, from, 8)
27 #else
28 #define COPY8B(to, from, ptr) \
29 if (((ptrdiff_t)(ptr) & 0x3) == 0) { \
30 HALFPTR(to)[0] = HALFPTR(from)[0]; \
31 HALFPTR(to)[1] = HALFPTR(from)[1]; \
32 } else if (((ptrdiff_t)(ptr) & 0x1) == 0) { \
33 SHORTPTR(to)[0] = SHORTPTR(from)[0]; \
34 SHORTPTR(to)[1] = SHORTPTR(from)[1]; \
35 SHORTPTR(to)[2] = SHORTPTR(from)[2]; \
36 SHORTPTR(to)[3] = SHORTPTR(from)[3]; \
37 } else { \
38 BYTEPTR(to)[0] = BYTEPTR(from)[0]; \
39 BYTEPTR(to)[1] = BYTEPTR(from)[1]; \
40 BYTEPTR(to)[2] = BYTEPTR(from)[2]; \
41 BYTEPTR(to)[3] = BYTEPTR(from)[3]; \
42 BYTEPTR(to)[4] = BYTEPTR(from)[4]; \
43 BYTEPTR(to)[5] = BYTEPTR(from)[5]; \
44 BYTEPTR(to)[6] = BYTEPTR(from)[6]; \
45 BYTEPTR(to)[7] = BYTEPTR(from)[7]; \
46 }
47 #endif
48 #define COPY8BTOHALF(to, from) COPY8B(to, from, from)
49 #define COPY8BFROMHALF(to, from) COPY8B(to, from, to)
50
51 static void
52 DES_ECB(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
53 {
54 while (len) {
55 DES_Do1Block(cx->ks0, in, out);
56 len -= 8;
57 in += 8;
58 out += 8;
59 }
60 }
61
62 static void
63 DES_EDE3_ECB(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
64 {
65 while (len) {
66 DES_Do1Block(cx->ks0, in, out);
67 len -= 8;
68 in += 8;
69 DES_Do1Block(cx->ks1, out, out);
70 DES_Do1Block(cx->ks2, out, out);
71 out += 8;
72 }
73 }
74
75 static void
76 DES_CBCEn(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
77 {
78 const BYTE * bufend = in + len;
79 HALF vec[2];
80
81 while (in != bufend) {
82 COPY8BTOHALF(vec, in);
83 in += 8;
84 vec[0] ^= cx->iv[0];
85 vec[1] ^= cx->iv[1];
86 DES_Do1Block( cx->ks0, (BYTE *)vec, (BYTE *)cx->iv);
87 COPY8BFROMHALF(out, cx->iv);
88 out += 8;
89 }
90 }
91
92 static void
93 DES_CBCDe(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
94 {
95 const BYTE * bufend;
96 HALF oldciphertext[2];
97 HALF plaintext [2];
98
99 for (bufend = in + len; in != bufend; ) {
100 oldciphertext[0] = cx->iv[0];
101 oldciphertext[1] = cx->iv[1];
102 COPY8BTOHALF(cx->iv, in);
103 in += 8;
104 DES_Do1Block(cx->ks0, (BYTE *)cx->iv, (BYTE *)plaintext);
105 plaintext[0] ^= oldciphertext[0];
106 plaintext[1] ^= oldciphertext[1];
107 COPY8BFROMHALF(out, plaintext);
108 out += 8;
109 }
110 }
111
112 static void
113 DES_EDE3CBCEn(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
114 {
115 const BYTE * bufend = in + len;
116 HALF vec[2];
117
118 while (in != bufend) {
119 COPY8BTOHALF(vec, in);
120 in += 8;
121 vec[0] ^= cx->iv[0];
122 vec[1] ^= cx->iv[1];
123 DES_Do1Block( cx->ks0, (BYTE *)vec, (BYTE *)cx->iv);
124 DES_Do1Block( cx->ks1, (BYTE *)cx->iv, (BYTE *)cx->iv);
125 DES_Do1Block( cx->ks2, (BYTE *)cx->iv, (BYTE *)cx->iv);
126 COPY8BFROMHALF(out, cx->iv);
127 out += 8;
128 }
129 }
130
131 static void
132 DES_EDE3CBCDe(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
133 {
134 const BYTE * bufend;
135 HALF oldciphertext[2];
136 HALF plaintext [2];
137
138 for (bufend = in + len; in != bufend; ) {
139 oldciphertext[0] = cx->iv[0];
140 oldciphertext[1] = cx->iv[1];
141 COPY8BTOHALF(cx->iv, in);
142 in += 8;
143 DES_Do1Block(cx->ks0, (BYTE *)cx->iv, (BYTE *)plaintext);
144 DES_Do1Block(cx->ks1, (BYTE *)plaintext, (BYTE *)plaintext);
145 DES_Do1Block(cx->ks2, (BYTE *)plaintext, (BYTE *)plaintext);
146 plaintext[0] ^= oldciphertext[0];
147 plaintext[1] ^= oldciphertext[1];
148 COPY8BFROMHALF(out, plaintext);
149 out += 8;
150 }
151 }
152
153 DESContext *
154 DES_AllocateContext(void)
155 {
156 return PORT_ZNew(DESContext);
157 }
158
159 SECStatus
160 DES_InitContext(DESContext *cx, const unsigned char *key, unsigned int keylen,
161 const unsigned char *iv, int mode, unsigned int encrypt,
162 unsigned int unused)
163 {
164 DESDirection opposite;
165 if (!cx) {
166 PORT_SetError(SEC_ERROR_INVALID_ARGS);
167 return SECFailure;
168 }
169 cx->direction = encrypt ? DES_ENCRYPT : DES_DECRYPT;
170 opposite = encrypt ? DES_DECRYPT : DES_ENCRYPT;
171 switch (mode) {
172 case NSS_DES: /* DES ECB */
173 DES_MakeSchedule( cx->ks0, key, cx->direction);
174 cx->worker = &DES_ECB;
175 break;
176
177 case NSS_DES_EDE3: /* DES EDE ECB */
178 cx->worker = &DES_EDE3_ECB;
179 if (encrypt) {
180 DES_MakeSchedule(cx->ks0, key, cx->direction);
181 DES_MakeSchedule(cx->ks1, key + 8, opposite);
182 DES_MakeSchedule(cx->ks2, key + 16, cx->direction);
183 } else {
184 DES_MakeSchedule(cx->ks2, key, cx->direction);
185 DES_MakeSchedule(cx->ks1, key + 8, opposite);
186 DES_MakeSchedule(cx->ks0, key + 16, cx->direction);
187 }
188 break;
189
190 case NSS_DES_CBC: /* DES CBC */
191 COPY8BTOHALF(cx->iv, iv);
192 cx->worker = encrypt ? &DES_CBCEn : &DES_CBCDe;
193 DES_MakeSchedule(cx->ks0, key, cx->direction);
194 break;
195
196 case NSS_DES_EDE3_CBC: /* DES EDE CBC */
197 COPY8BTOHALF(cx->iv, iv);
198 if (encrypt) {
199 cx->worker = &DES_EDE3CBCEn;
200 DES_MakeSchedule(cx->ks0, key, cx->direction);
201 DES_MakeSchedule(cx->ks1, key + 8, opposite);
202 DES_MakeSchedule(cx->ks2, key + 16, cx->direction);
203 } else {
204 cx->worker = &DES_EDE3CBCDe;
205 DES_MakeSchedule(cx->ks2, key, cx->direction);
206 DES_MakeSchedule(cx->ks1, key + 8, opposite);
207 DES_MakeSchedule(cx->ks0, key + 16, cx->direction);
208 }
209 break;
210
211 default:
212 PORT_SetError(SEC_ERROR_INVALID_ARGS);
213 return SECFailure;
214 }
215 return SECSuccess;
216 }
217
218 DESContext *
219 DES_CreateContext(const BYTE * key, const BYTE *iv, int mode, PRBool encrypt)
220 {
221 DESContext *cx = PORT_ZNew(DESContext);
222 SECStatus rv = DES_InitContext(cx, key, 0, iv, mode, encrypt, 0);
223
224 if (rv != SECSuccess) {
225 PORT_ZFree(cx, sizeof *cx);
226 cx = NULL;
227 }
228 return cx;
229 }
230
231 void
232 DES_DestroyContext(DESContext *cx, PRBool freeit)
233 {
234 if (cx) {
235 memset(cx, 0, sizeof *cx);
236 if (freeit)
237 PORT_Free(cx);
238 }
239 }
240
241 SECStatus
242 DES_Encrypt(DESContext *cx, BYTE *out, unsigned int *outLen,
243 unsigned int maxOutLen, const BYTE *in, unsigned int inLen)
244 {
245
246 if ((inLen % 8) != 0 || maxOutLen < inLen || !cx ||
247 cx->direction != DES_ENCRYPT) {
248 PORT_SetError(SEC_ERROR_INVALID_ARGS);
249 return SECFailure;
250 }
251
252 cx->worker(cx, out, in, inLen);
253 if (outLen)
254 *outLen = inLen;
255 return SECSuccess;
256 }
257
258 SECStatus
259 DES_Decrypt(DESContext *cx, BYTE *out, unsigned int *outLen,
260 unsigned int maxOutLen, const BYTE *in, unsigned int inLen)
261 {
262
263 if ((inLen % 8) != 0 || maxOutLen < inLen || !cx ||
264 cx->direction != DES_DECRYPT) {
265 PORT_SetError(SEC_ERROR_INVALID_ARGS);
266 return SECFailure;
267 }
268
269 cx->worker(cx, out, in, inLen);
270 if (outLen)
271 *outLen = inLen;
272 return SECSuccess;
273 }
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)