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
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)