Mercurial > trustbridge > nss-cmake-static
comparison nss/lib/freebl/ctr.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 /* This Source Code Form is subject to the terms of the Mozilla Public | |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
4 | |
5 #ifdef FREEBL_NO_DEPEND | |
6 #include "stubs.h" | |
7 #endif | |
8 #include "prtypes.h" | |
9 #include "blapit.h" | |
10 #include "blapii.h" | |
11 #include "ctr.h" | |
12 #include "pkcs11t.h" | |
13 #include "secerr.h" | |
14 | |
15 #ifdef USE_HW_AES | |
16 #include "intel-aes.h" | |
17 #include "rijndael.h" | |
18 #endif | |
19 | |
20 SECStatus | |
21 CTR_InitContext(CTRContext *ctr, void *context, freeblCipherFunc cipher, | |
22 const unsigned char *param, unsigned int blocksize) | |
23 { | |
24 const CK_AES_CTR_PARAMS *ctrParams = (const CK_AES_CTR_PARAMS *)param; | |
25 | |
26 if (ctrParams->ulCounterBits == 0 || | |
27 ctrParams->ulCounterBits > blocksize * PR_BITS_PER_BYTE) { | |
28 PORT_SetError(SEC_ERROR_INVALID_ARGS); | |
29 return SECFailure; | |
30 } | |
31 | |
32 /* Invariant: 0 < ctr->bufPtr <= blocksize */ | |
33 ctr->bufPtr = blocksize; /* no unused data in the buffer */ | |
34 ctr->cipher = cipher; | |
35 ctr->context = context; | |
36 ctr->counterBits = ctrParams->ulCounterBits; | |
37 if (blocksize > sizeof(ctr->counter) || | |
38 blocksize > sizeof(ctrParams->cb)) { | |
39 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); | |
40 return SECFailure; | |
41 } | |
42 PORT_Memcpy(ctr->counter, ctrParams->cb, blocksize); | |
43 return SECSuccess; | |
44 } | |
45 | |
46 CTRContext * | |
47 CTR_CreateContext(void *context, freeblCipherFunc cipher, | |
48 const unsigned char *param, unsigned int blocksize) | |
49 { | |
50 CTRContext *ctr; | |
51 SECStatus rv; | |
52 | |
53 /* first fill in the Counter context */ | |
54 ctr = PORT_ZNew(CTRContext); | |
55 if (ctr == NULL) { | |
56 return NULL; | |
57 } | |
58 rv = CTR_InitContext(ctr, context, cipher, param, blocksize); | |
59 if (rv != SECSuccess) { | |
60 CTR_DestroyContext(ctr, PR_TRUE); | |
61 ctr = NULL; | |
62 } | |
63 return ctr; | |
64 } | |
65 | |
66 void | |
67 CTR_DestroyContext(CTRContext *ctr, PRBool freeit) | |
68 { | |
69 PORT_Memset(ctr, 0, sizeof(CTRContext)); | |
70 if (freeit) { | |
71 PORT_Free(ctr); | |
72 } | |
73 } | |
74 | |
75 /* | |
76 * Used by counter mode. Increment the counter block. Not all bits in the | |
77 * counter block are part of the counter, counterBits tells how many bits | |
78 * are part of the counter. The counter block is blocksize long. It's a | |
79 * big endian value. | |
80 * | |
81 * XXX Does not handle counter rollover. | |
82 */ | |
83 static void | |
84 ctr_GetNextCtr(unsigned char *counter, unsigned int counterBits, | |
85 unsigned int blocksize) | |
86 { | |
87 unsigned char *counterPtr = counter + blocksize - 1; | |
88 unsigned char mask, count; | |
89 | |
90 PORT_Assert(counterBits <= blocksize*PR_BITS_PER_BYTE); | |
91 while (counterBits >= PR_BITS_PER_BYTE) { | |
92 if (++(*(counterPtr--))) { | |
93 return; | |
94 } | |
95 counterBits -= PR_BITS_PER_BYTE; | |
96 } | |
97 if (counterBits == 0) { | |
98 return; | |
99 } | |
100 /* increment the final partial byte */ | |
101 mask = (1 << counterBits)-1; | |
102 count = ++(*counterPtr) & mask; | |
103 *counterPtr = ((*counterPtr) & ~mask) | count; | |
104 return; | |
105 } | |
106 | |
107 static void | |
108 ctr_xor(unsigned char *target, const unsigned char *x, | |
109 const unsigned char *y, unsigned int count) | |
110 { | |
111 unsigned int i; | |
112 for (i=0; i < count; i++) { | |
113 *target++ = *x++ ^ *y++; | |
114 } | |
115 } | |
116 | |
117 SECStatus | |
118 CTR_Update(CTRContext *ctr, unsigned char *outbuf, | |
119 unsigned int *outlen, unsigned int maxout, | |
120 const unsigned char *inbuf, unsigned int inlen, | |
121 unsigned int blocksize) | |
122 { | |
123 unsigned int tmp; | |
124 SECStatus rv; | |
125 | |
126 if (maxout < inlen) { | |
127 *outlen = inlen; | |
128 PORT_SetError(SEC_ERROR_OUTPUT_LEN); | |
129 return SECFailure; | |
130 } | |
131 *outlen = 0; | |
132 if (ctr->bufPtr != blocksize) { | |
133 unsigned int needed = PR_MIN(blocksize-ctr->bufPtr, inlen); | |
134 ctr_xor(outbuf, inbuf, ctr->buffer + ctr->bufPtr, needed); | |
135 ctr->bufPtr += needed; | |
136 outbuf += needed; | |
137 inbuf += needed; | |
138 *outlen += needed; | |
139 inlen -= needed; | |
140 if (inlen == 0) { | |
141 return SECSuccess; | |
142 } | |
143 PORT_Assert(ctr->bufPtr == blocksize); | |
144 } | |
145 | |
146 while (inlen >= blocksize) { | |
147 rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, blocksize, | |
148 ctr->counter, blocksize, blocksize); | |
149 ctr_GetNextCtr(ctr->counter, ctr->counterBits, blocksize); | |
150 if (rv != SECSuccess) { | |
151 return SECFailure; | |
152 } | |
153 ctr_xor(outbuf, inbuf, ctr->buffer, blocksize); | |
154 outbuf += blocksize; | |
155 inbuf += blocksize; | |
156 *outlen += blocksize; | |
157 inlen -= blocksize; | |
158 } | |
159 if (inlen == 0) { | |
160 return SECSuccess; | |
161 } | |
162 rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, blocksize, | |
163 ctr->counter, blocksize, blocksize); | |
164 ctr_GetNextCtr(ctr->counter, ctr->counterBits, blocksize); | |
165 if (rv != SECSuccess) { | |
166 return SECFailure; | |
167 } | |
168 ctr_xor(outbuf, inbuf, ctr->buffer, inlen); | |
169 ctr->bufPtr = inlen; | |
170 *outlen += inlen; | |
171 return SECSuccess; | |
172 } | |
173 | |
174 #if defined(USE_HW_AES) && defined(_MSC_VER) | |
175 SECStatus | |
176 CTR_Update_HW_AES(CTRContext *ctr, unsigned char *outbuf, | |
177 unsigned int *outlen, unsigned int maxout, | |
178 const unsigned char *inbuf, unsigned int inlen, | |
179 unsigned int blocksize) | |
180 { | |
181 unsigned int fullblocks; | |
182 unsigned int tmp; | |
183 SECStatus rv; | |
184 | |
185 if (maxout < inlen) { | |
186 *outlen = inlen; | |
187 PORT_SetError(SEC_ERROR_OUTPUT_LEN); | |
188 return SECFailure; | |
189 } | |
190 *outlen = 0; | |
191 if (ctr->bufPtr != blocksize) { | |
192 unsigned int needed = PR_MIN(blocksize-ctr->bufPtr, inlen); | |
193 ctr_xor(outbuf, inbuf, ctr->buffer + ctr->bufPtr, needed); | |
194 ctr->bufPtr += needed; | |
195 outbuf += needed; | |
196 inbuf += needed; | |
197 *outlen += needed; | |
198 inlen -= needed; | |
199 if (inlen == 0) { | |
200 return SECSuccess; | |
201 } | |
202 PORT_Assert(ctr->bufPtr == blocksize); | |
203 } | |
204 | |
205 intel_aes_ctr_worker(((AESContext*)(ctr->context))->Nr)( | |
206 ctr, outbuf, outlen, maxout, inbuf, inlen, blocksize); | |
207 /* XXX intel_aes_ctr_worker should set *outlen. */ | |
208 PORT_Assert(*outlen == 0); | |
209 fullblocks = (inlen/blocksize)*blocksize; | |
210 *outlen += fullblocks; | |
211 outbuf += fullblocks; | |
212 inbuf += fullblocks; | |
213 inlen -= fullblocks; | |
214 | |
215 if (inlen == 0) { | |
216 return SECSuccess; | |
217 } | |
218 rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, blocksize, | |
219 ctr->counter, blocksize, blocksize); | |
220 ctr_GetNextCtr(ctr->counter, ctr->counterBits, blocksize); | |
221 if (rv != SECSuccess) { | |
222 return SECFailure; | |
223 } | |
224 ctr_xor(outbuf, inbuf, ctr->buffer, inlen); | |
225 ctr->bufPtr = inlen; | |
226 *outlen += inlen; | |
227 return SECSuccess; | |
228 } | |
229 #endif |