Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(136)

Side by Side Diff: nss/mozilla/security/nss/lib/freebl/ctr.c

Issue 10919163: Add GCM, CTR, and CTS modes to AES. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(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
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 SECStatus
16 CTR_InitContext(CTRContext *ctr, void *context, freeblCipherFunc cipher,
17 const unsigned char *param, unsigned int blocksize)
18 {
19 const CK_AES_CTR_PARAMS *ctrParams = (const CK_AES_CTR_PARAMS *)param;
20
21 ctr->bufPtr = blocksize; /* no unused data in the buffer */
22 ctr->cipher = cipher;
23 ctr->context = context;
24 ctr->counterBits = ctrParams->ulCounterBits;
25 if (blocksize > sizeof(ctr->counter) ||
26 blocksize > sizeof(ctrParams->cb) ||
27 ctr->counterBits > blocksize * PR_BITS_PER_BYTE) {
28 PORT_SetError(SEC_ERROR_INVALID_ARGS);
29 return SECFailure;
30 }
31 PORT_Memcpy(ctr->counter, ctrParams->cb, blocksize);
32 return SECSuccess;
33 }
34
35 CTRContext *
36 CTR_CreateContext(void *context, freeblCipherFunc cipher,
37 const unsigned char *param, unsigned int blocksize)
38 {
39 CTRContext *ctr;
40 SECStatus rv;
41
42 /* first fill in the Counter context */
43 ctr = PORT_ZNew(CTRContext);
44 if (ctr == NULL) {
45 return NULL;
46 }
47 rv = CTR_InitContext(ctr, context, cipher, param, blocksize);
48 if (rv != SECSuccess) {
49 CTR_DestroyContext(ctr, PR_TRUE);
50 ctr = NULL;
51 }
52 return ctr;
53 }
54
55 void
56 CTR_DestroyContext(CTRContext *ctr, PRBool freeit)
57 {
58 PORT_Memset(ctr, 0, sizeof(CTRContext));
59 if (freeit) {
60 PORT_Free(ctr);
61 }
62 }
63
64 /*
65 * Used by counter mode. Increment the counter block. Not all bits in the
66 * counter block are part of the counter, counterBits tells how many bits
67 * are part of the counter. The counter block is blocksize long. It's a
68 * big endian value.
69 *
70 * XXX Does not handle counter overflow.
71 */
72 static void
73 ctr_GetNextCtr(unsigned char *counter, unsigned int counterBits,
74 unsigned int blocksize)
75 {
76 unsigned char *counterPtr = counter + blocksize - 1;
77 unsigned char mask, count;
78
79 PORT_Assert(counterBits <= blocksize*PR_BITS_PER_BYTE);
80 while (counterBits >= PR_BITS_PER_BYTE) {
81 if (++(*(counterPtr--))) {
82 return;
83 }
84 counterBits -= PR_BITS_PER_BYTE;
85 }
86 if (counterBits == 0) {
87 return;
88 }
89 /* increment the final partial byte */
90 mask = (1 << counterBits)-1;
91 count = ++(*counterPtr) & mask;
92 *counterPtr = ((*counterPtr) & ~mask) | count;
93 return;
94 }
95
96 static void
97 ctr_xor(unsigned char *target, const unsigned char *x,
98 const unsigned char *y, unsigned int count)
99 {
100 unsigned int i;
101 for (i=0; i < count; i++) {
102 *target++ = *x++ ^ *y++;
103 }
104 }
105
106 SECStatus
107 CTR_Update(CTRContext *ctr, unsigned char *outbuf,
108 unsigned int *outlen, unsigned int maxout,
109 const unsigned char *inbuf, unsigned int inlen,
110 unsigned int blocksize)
111 {
112 unsigned int tmp;
113 SECStatus rv;
114
115 if (maxout < inlen) {
116 *outlen = inlen;
117 PORT_SetError(SEC_ERROR_OUTPUT_LEN);
118 return SECFailure;
119 }
120 *outlen = 0;
121 if (ctr->bufPtr != blocksize) {
122 unsigned int needed = PR_MIN(blocksize-ctr->bufPtr, inlen);
123 ctr_xor(outbuf, inbuf, ctr->buffer+ctr->bufPtr, needed);
124 ctr->bufPtr += needed;
125 outbuf += needed;
126 inbuf += needed;
127 *outlen += needed;
128 inlen -= needed;
129 if (inlen == 0) {
130 return SECSuccess;
131 }
132 }
133
134 while (inlen >= blocksize) {
135 rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, blocksize,
136 ctr->counter, blocksize, blocksize);
137 ctr_GetNextCtr(ctr->counter, ctr->counterBits, blocksize);
138 if (rv != SECSuccess) {
139 return SECFailure;
140 }
141 ctr_xor(outbuf, inbuf, ctr->buffer, blocksize);
142 outbuf += blocksize;
143 inbuf += blocksize;
144 *outlen += blocksize;
145 inlen -= blocksize;
146 }
147 if (inlen == 0) {
148 return SECSuccess;
149 }
150 rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, blocksize,
151 ctr->counter, blocksize, blocksize);
152 ctr_GetNextCtr(ctr->counter, ctr->counterBits, blocksize);
153 if (rv != SECSuccess) {
154 return SECFailure;
155 }
156 ctr_xor(outbuf, inbuf, ctr->buffer, inlen);
157 ctr->bufPtr = inlen;
158 *outlen += inlen;
159 return SECSuccess;
160 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698