|
OLD | NEW |
---|---|
(Empty) | |
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 /* $Id: gsm.c,v 1.27 2012/04/25 14:49:43 gerv%gerv.net Exp $ */ | |
5 | |
6 #ifdef FREEBL_NO_DEPEND | |
7 #include "stubs.h" | |
8 #endif | |
9 #include "prtypes.h" | |
10 #include "blapit.h" | |
11 #include "blapii.h" | |
12 #include "ctr.h" | |
13 #include "pkcs11t.h" | |
14 #include "secerr.h" | |
15 | |
16 SECStatus | |
17 CTR_InitContext(CTRContext *ctr, void *context, freeblCipherFunc cipher, | |
18 const unsigned char *param, unsigned int blocksize) | |
19 { | |
20 const CK_AES_CTR_PARAMS *ctrParams = (const CK_AES_CTR_PARAMS *)param; | |
21 | |
22 ctr->bufPtr = blocksize; /* no unused data in the buffer */ | |
23 ctr->cipher = cipher; | |
24 ctr->context = context; | |
25 ctr->counterBits = ctrParams->ulCounterBits; | |
Ryan Sleevi
2012/09/11 19:34:30
s/= ctrParams/= ctrParams/ (extra space)
Ryan Sleevi
2012/09/11 19:34:30
It seems you should be checking here, instead of /
| |
26 PORT_Memcpy(ctr->counter, ctrParams->cb, blocksize); | |
27 return SECSuccess; | |
28 } | |
29 | |
30 CTRContext * | |
31 CTR_CreateContext(void *context, freeblCipherFunc cipher, | |
32 const unsigned char *param, unsigned int blocksize) | |
33 { | |
34 CTRContext *ctr; | |
35 SECStatus rv; | |
36 | |
37 /* first fill in the Counter context */ | |
38 ctr = PORT_ZNew(CTRContext); | |
39 if (ctr == NULL) { | |
40 return NULL; | |
41 } | |
42 rv = CTR_InitContext(ctr, context, cipher, param, blocksize); | |
43 if (rv != SECSuccess) { | |
44 CTR_DestroyContext(ctr, PR_TRUE); | |
45 ctr = NULL; | |
46 } | |
47 return ctr; | |
48 } | |
49 | |
50 void | |
51 CTR_DestroyContext(CTRContext *ctr, PRBool freeit) | |
52 { | |
53 PORT_Memset(ctr, 0, sizeof (CTRContext)); | |
Ryan Sleevi
2012/09/11 19:34:30
Why the additional memset here?
In looking at the
wtc
2012/09/14 01:16:42
The form used here is also common. See, for exampl
rjrejyea
2012/09/19 21:43:40
That's a very good suggestion.
bob
| |
54 if (freeit) { | |
55 PORT_Free(ctr); | |
56 } | |
57 } | |
58 | |
59 /* | |
60 * Used by counter mode. Increment the counter block. Not all bits in the | |
61 * counter block are part of the counter, counter_bits tells how many bits | |
62 * are part of the counter. The counter_block is block_size long. It's a | |
63 * big endian value. | |
64 */ | |
65 static void | |
66 ctr_GetNextCtr(unsigned char *counter, unsigned int counterBits, | |
67 unsigned int blocksize) | |
68 { | |
69 unsigned char *counterPtr = counter + blocksize - 1; | |
70 unsigned char mask, count; | |
71 | |
72 PORT_Assert(counterBits <= blocksize*BITS_PER_BYTE); | |
73 while (counterBits >= BITS_PER_BYTE) { | |
74 if (++(*(counterPtr--))) { | |
75 return; | |
wtc
2012/09/19 22:19:33
Since counterBits is usually a multiple of 8, the
| |
76 } | |
77 counterBits -= BITS_PER_BYTE; | |
78 } | |
79 if (counterBits == 0) { | |
80 return; | |
81 } | |
82 /* increment the final partial byte */ | |
83 mask = (1 << counterBits)-1; | |
84 count = (*counterPtr)++ & mask; | |
85 *counterPtr = ((*counterPtr) & ~mask) | count; | |
Ryan Sleevi
2012/09/11 19:34:30
This does not appear to handle counter rollover co
rjrejyea
2012/09/19 21:43:40
I was under the impression that the counter was su
Ryan Sleevi
2012/09/19 21:53:15
Sorry, this may have been read opposite of how I i
rjrejyea
2012/09/19 21:59:36
OK, so the bug here is that we need to store *coun
Ryan Sleevi
2012/09/19 22:06:21
Also, I didn't see the check here (or elsewhere) a
Ryan Sleevi
2012/09/19 22:09:42
I don't think that will be sufficient. *counterPtr
| |
86 return; | |
87 } | |
88 | |
89 static void | |
90 ctr_xor(unsigned char *target, const unsigned char *x, | |
91 const unsigned char *y, int count) | |
92 { | |
93 int i; | |
94 for (i=0; i < count; i++) { | |
95 *target++ = *x++ ^ *y++; | |
96 } | |
97 } | |
98 | |
99 SECStatus | |
100 CTR_Update(CTRContext *ctr, unsigned char *outbuf, | |
101 unsigned int *outlen, unsigned int maxout, | |
102 const unsigned char *inbuf, unsigned int inlen, | |
103 unsigned int blocksize) | |
104 { | |
105 unsigned char cipherblock[MAX_BLOCK_SIZE]; | |
106 unsigned int tmp; | |
107 SECStatus rv; | |
108 | |
109 if (maxout < inlen) { | |
110 *outlen = inlen; | |
111 PORT_SetError(SEC_ERROR_OUTPUT_LEN); | |
112 return SECFailure; | |
113 } | |
114 *outlen = 0; | |
115 if (ctr->bufPtr != blocksize) { | |
116 int needed = PR_MIN(blocksize-ctr->bufPtr, inlen); | |
117 ctr_xor(outbuf, inbuf, ctr->buffer+ctr->bufPtr, needed); | |
118 ctr->bufPtr += needed; | |
119 outbuf += needed; | |
120 inbuf += needed; | |
121 *outlen += needed; | |
122 inlen -= needed; | |
123 if (inlen == 0) { | |
124 return SECSuccess; | |
125 } | |
126 } | |
127 | |
128 while (inlen >= blocksize) { | |
129 rv = (*ctr->cipher)(ctr->context, cipherblock, &tmp, blocksize, | |
130 ctr->counter, blocksize, blocksize); | |
131 ctr_GetNextCtr(ctr->counter, ctr->counterBits, blocksize); | |
132 if (rv != SECSuccess) { | |
133 return SECFailure; | |
134 } | |
135 ctr_xor(outbuf, inbuf, cipherblock, blocksize); | |
136 outbuf += blocksize; | |
137 inbuf += blocksize; | |
138 *outlen += blocksize; | |
139 inlen -= blocksize; | |
140 } | |
141 if (inlen == 0) { | |
142 return SECSuccess; | |
143 } | |
144 rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, blocksize, | |
145 ctr->counter, blocksize, blocksize); | |
146 ctr_GetNextCtr(ctr->counter, ctr->counterBits, blocksize); | |
147 if (rv != SECSuccess) { | |
148 return SECFailure; | |
149 } | |
150 ctr_xor(outbuf, inbuf, ctr->buffer, inlen); | |
151 ctr->bufPtr = inlen; | |
152 *outlen += inlen; | |
153 return SECSuccess; | |
154 } | |
OLD | NEW |