summaryrefslogtreecommitdiff
path: root/nss/lib/freebl/cts.c
diff options
context:
space:
mode:
Diffstat (limited to 'nss/lib/freebl/cts.c')
-rw-r--r--nss/lib/freebl/cts.c122
1 files changed, 64 insertions, 58 deletions
diff --git a/nss/lib/freebl/cts.c b/nss/lib/freebl/cts.c
index 984e05b..99ccebb 100644
--- a/nss/lib/freebl/cts.c
+++ b/nss/lib/freebl/cts.c
@@ -20,17 +20,17 @@ struct CTSContextStr {
CTSContext *
CTS_CreateContext(void *context, freeblCipherFunc cipher,
- const unsigned char *iv, unsigned int blocksize)
+ const unsigned char *iv, unsigned int blocksize)
{
- CTSContext *cts;
+ CTSContext *cts;
if (blocksize > MAX_BLOCK_SIZE) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return NULL;
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return NULL;
}
cts = PORT_ZNew(CTSContext);
if (cts == NULL) {
- return NULL;
+ return NULL;
}
PORT_Memcpy(cts->iv, iv, blocksize);
cts->cipher = cipher;
@@ -42,10 +42,10 @@ void
CTS_DestroyContext(CTSContext *cts, PRBool freeit)
{
if (freeit) {
- PORT_Free(cts);
+ PORT_Free(cts);
}
}
-
+
/*
* See addemdum to NIST SP 800-38A
* Generically handle cipher text stealing. Basically this is doing CBC
@@ -75,7 +75,7 @@ CTS_DestroyContext(CTSContext *cts, PRBool freeit)
* if (pad) {
* memcpy(tmp, outbuf+*outlen-blocksize, blocksize);
* memcpy(outbuf+*outlen-pad,outbuf+*outlen-blocksize-pad, pad);
- * memcpy(outbuf+*outlen-blocksize-pad, tmp, blocksize);
+ * memcpy(outbuf+*outlen-blocksize-pad, tmp, blocksize);
* }
* CS-3 (Kerberos): do
* unsigned char tmp[MAX_BLOCK_SIZE];
@@ -85,41 +85,42 @@ CTS_DestroyContext(CTSContext *cts, PRBool freeit)
* }
* memcpy(tmp, outbuf+*outlen-blocksize, blocksize);
* memcpy(outbuf+*outlen-pad,outbuf+*outlen-blocksize-pad, pad);
- * memcpy(outbuf+*outlen-blocksize-pad, tmp, blocksize);
+ * memcpy(outbuf+*outlen-blocksize-pad, tmp, blocksize);
*/
SECStatus
CTS_EncryptUpdate(CTSContext *cts, unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- const unsigned char *inbuf, unsigned int inlen,
- unsigned int blocksize)
+ unsigned int *outlen, unsigned int maxout,
+ const unsigned char *inbuf, unsigned int inlen,
+ unsigned int blocksize)
{
unsigned char lastBlock[MAX_BLOCK_SIZE];
unsigned int tmp;
int fullblocks;
int written;
+ unsigned char *saveout = outbuf;
SECStatus rv;
if (inlen < blocksize) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return SECFailure;
}
if (maxout < inlen) {
- *outlen = inlen;
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
+ *outlen = inlen;
+ PORT_SetError(SEC_ERROR_OUTPUT_LEN);
+ return SECFailure;
}
- fullblocks = (inlen/blocksize)*blocksize;
+ fullblocks = (inlen / blocksize) * blocksize;
rv = (*cts->cipher)(cts->context, outbuf, outlen, maxout, inbuf,
- fullblocks, blocksize);
+ fullblocks, blocksize);
if (rv != SECSuccess) {
- return SECFailure;
+ return SECFailure;
}
*outlen = fullblocks; /* AES low level doesn't set outlen */
inbuf += fullblocks;
inlen -= fullblocks;
if (inlen == 0) {
- return SECSuccess;
+ return SECSuccess;
}
written = *outlen - (blocksize - inlen);
outbuf += written;
@@ -137,16 +138,19 @@ CTS_EncryptUpdate(CTSContext *cts, unsigned char *outbuf,
PORT_Memcpy(lastBlock, inbuf, inlen);
PORT_Memset(lastBlock + inlen, 0, blocksize - inlen);
rv = (*cts->cipher)(cts->context, outbuf, &tmp, maxout, lastBlock,
- blocksize, blocksize);
+ blocksize, blocksize);
PORT_Memset(lastBlock, 0, blocksize);
if (rv == SECSuccess) {
- *outlen = written + blocksize;
+ *outlen = written + blocksize;
+ } else {
+ PORT_Memset(saveout, 0, written + blocksize);
}
return rv;
}
-
-#define XOR_BLOCK(x,y,count) for(i=0; i < count; i++) x[i] = x[i] ^ y[i]
+#define XOR_BLOCK(x, y, count) \
+ for (i = 0; i < count; i++) \
+ x[i] = x[i] ^ y[i]
/*
* See addemdum to NIST SP 800-38A
@@ -160,7 +164,7 @@ CTS_EncryptUpdate(CTSContext *cts, unsigned char *outbuf,
* if (pad) {
* memcpy(tmp, inbuf+inlen-blocksize-pad, blocksize);
* memcpy(inbuf+inlen-blocksize-pad,inbuf+inlen-pad, pad);
- * memcpy(inbuf+inlen-blocksize, tmp, blocksize);
+ * memcpy(inbuf+inlen-blocksize, tmp, blocksize);
* }
* CS-3 (Kerberos): do
* unsigned char tmp[MAX_BLOCK_SIZE];
@@ -170,13 +174,13 @@ CTS_EncryptUpdate(CTSContext *cts, unsigned char *outbuf,
* }
* memcpy(tmp, inbuf+inlen-blocksize-pad, blocksize);
* memcpy(inbuf+inlen-blocksize-pad,inbuf+inlen-pad, pad);
- * memcpy(inbuf+inlen-blocksize, tmp, blocksize);
+ * memcpy(inbuf+inlen-blocksize, tmp, blocksize);
*/
SECStatus
CTS_DecryptUpdate(CTSContext *cts, unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- const unsigned char *inbuf, unsigned int inlen,
- unsigned int blocksize)
+ unsigned int *outlen, unsigned int maxout,
+ const unsigned char *inbuf, unsigned int inlen,
+ unsigned int blocksize)
{
unsigned char *Pn;
unsigned char Cn_2[MAX_BLOCK_SIZE]; /* block Cn-2 */
@@ -184,23 +188,24 @@ CTS_DecryptUpdate(CTSContext *cts, unsigned char *outbuf,
unsigned char Cn[MAX_BLOCK_SIZE]; /* block Cn */
unsigned char lastBlock[MAX_BLOCK_SIZE];
const unsigned char *tmp;
+ unsigned char *saveout = outbuf;
unsigned int tmpLen;
unsigned int fullblocks, pad;
unsigned int i;
SECStatus rv;
if (inlen < blocksize) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return SECFailure;
}
if (maxout < inlen) {
- *outlen = inlen;
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
+ *outlen = inlen;
+ PORT_SetError(SEC_ERROR_OUTPUT_LEN);
+ return SECFailure;
}
- fullblocks = (inlen/blocksize)*blocksize;
+ fullblocks = (inlen / blocksize) * blocksize;
/* even though we expect the input to be CS-1, CS-2 is easier to parse,
* so convert to CS-2 immediately. NOTE: this is the same code as in
@@ -209,34 +214,33 @@ CTS_DecryptUpdate(CTSContext *cts, unsigned char *outbuf,
*/
pad = inlen - fullblocks;
if (pad != 0) {
- if (inbuf != outbuf) {
- memcpy(outbuf, inbuf, inlen);
- /* keep the names so we logically know how we are using the
- * buffers */
- inbuf = outbuf;
- }
- memcpy(lastBlock, inbuf+inlen-blocksize, blocksize);
- /* we know inbuf == outbuf now, inbuf is declared const and can't
- * be the target, so use outbuf for the target here */
- memcpy(outbuf+inlen-pad, inbuf+inlen-blocksize-pad, pad);
- memcpy(outbuf+inlen-blocksize-pad, lastBlock, blocksize);
+ if (inbuf != outbuf) {
+ memcpy(outbuf, inbuf, inlen);
+ /* keep the names so we logically know how we are using the
+ * buffers */
+ inbuf = outbuf;
+ }
+ memcpy(lastBlock, inbuf + inlen - blocksize, blocksize);
+ /* we know inbuf == outbuf now, inbuf is declared const and can't
+ * be the target, so use outbuf for the target here */
+ memcpy(outbuf + inlen - pad, inbuf + inlen - blocksize - pad, pad);
+ memcpy(outbuf + inlen - blocksize - pad, lastBlock, blocksize);
}
/* save the previous to last block so we can undo the misordered
* chaining */
- tmp = (fullblocks < blocksize*2) ? cts->iv :
- inbuf+fullblocks-blocksize*2;
+ tmp = (fullblocks < blocksize * 2) ? cts->iv : inbuf + fullblocks - blocksize * 2;
PORT_Memcpy(Cn_2, tmp, blocksize);
- PORT_Memcpy(Cn, inbuf+fullblocks-blocksize, blocksize);
+ PORT_Memcpy(Cn, inbuf + fullblocks - blocksize, blocksize);
rv = (*cts->cipher)(cts->context, outbuf, outlen, maxout, inbuf,
- fullblocks, blocksize);
+ fullblocks, blocksize);
if (rv != SECSuccess) {
- return SECFailure;
+ return SECFailure;
}
*outlen = fullblocks; /* AES low level doesn't set outlen */
inbuf += fullblocks;
inlen -= fullblocks;
if (inlen == 0) {
- return SECSuccess;
+ return SECSuccess;
}
outbuf += fullblocks;
@@ -244,7 +248,7 @@ CTS_DecryptUpdate(CTSContext *cts, unsigned char *outbuf,
PORT_Memset(lastBlock, 0, blocksize);
PORT_Memcpy(lastBlock, inbuf, inlen);
PORT_Memcpy(Cn_1, inbuf, inlen);
- Pn = outbuf-blocksize;
+ Pn = outbuf - blocksize;
/* inbuf points to Cn-1* in the input buffer */
/* NOTE: below there are 2 sections marked "make up for the out of order
* cbc decryption". You may ask, what is going on here.
@@ -278,9 +282,11 @@ CTS_DecryptUpdate(CTSContext *cts, unsigned char *outbuf,
* points to where Pn-1 needs to reside. From here on out read Pn in
* the code as really Pn-1. */
rv = (*cts->cipher)(cts->context, Pn, &tmpLen, blocksize, lastBlock,
- blocksize, blocksize);
+ blocksize, blocksize);
if (rv != SECSuccess) {
- return SECFailure;
+ PORT_Memset(lastBlock, 0, blocksize);
+ PORT_Memset(saveout, 0, *outlen);
+ return SECFailure;
}
/* make up for the out of order CBC decryption */
XOR_BLOCK(Pn, Cn_2, blocksize);
@@ -290,8 +296,8 @@ CTS_DecryptUpdate(CTSContext *cts, unsigned char *outbuf,
/* This makes Cn the last block for the next decrypt operation, which
* matches the encrypt. We don't care about the contexts of last block,
* only the side effect of setting the internal IV */
- (void) (*cts->cipher)(cts->context, lastBlock, &tmpLen, blocksize, Cn,
- blocksize, blocksize);
+ (void)(*cts->cipher)(cts->context, lastBlock, &tmpLen, blocksize, Cn,
+ blocksize, blocksize);
/* clear last block. At this point last block contains Pn xor Cn_1 xor
* Cn_2, both of with an attacker would know, so we need to clear this
* buffer out */