diff options
Diffstat (limited to 'security/nss/lib/ssl/selfencrypt.c')
-rw-r--r-- | security/nss/lib/ssl/selfencrypt.c | 101 |
1 files changed, 54 insertions, 47 deletions
diff --git a/security/nss/lib/ssl/selfencrypt.c b/security/nss/lib/ssl/selfencrypt.c index 6d6e25cfc..1c70f7635 100644 --- a/security/nss/lib/ssl/selfencrypt.c +++ b/security/nss/lib/ssl/selfencrypt.c @@ -11,7 +11,6 @@ #include "pk11func.h" #include "ssl.h" #include "sslt.h" -#include "ssl3encode.h" #include "sslimpl.h" #include "selfencrypt.h" @@ -121,12 +120,11 @@ ssl_SelfEncryptProtectInt( PRUint8 *out, unsigned int *outLen, unsigned int maxOutLen) { unsigned int len; + unsigned int lenOffset; unsigned char iv[AES_BLOCK_SIZE]; SECItem ivItem = { siBuffer, iv, sizeof(iv) }; - unsigned char mac[SHA256_LENGTH]; /* SHA-256 */ - unsigned int macLen; - SECItem outItem = { siBuffer, out, maxOutLen }; - SECItem lengthBytesItem; + /* Write directly to out. */ + sslBuffer buf = SSL_BUFFER_FIXED(out, maxOutLen); SECStatus rv; /* Generate a random IV */ @@ -137,52 +135,54 @@ ssl_SelfEncryptProtectInt( } /* Add header. */ - rv = ssl3_AppendToItem(&outItem, keyName, SELF_ENCRYPT_KEY_NAME_LEN); + rv = sslBuffer_Append(&buf, keyName, SELF_ENCRYPT_KEY_NAME_LEN); if (rv != SECSuccess) { return SECFailure; } - rv = ssl3_AppendToItem(&outItem, iv, sizeof(iv)); + rv = sslBuffer_Append(&buf, iv, sizeof(iv)); if (rv != SECSuccess) { return SECFailure; } - /* Skip forward by two so we can encode the ciphertext in place. */ - lengthBytesItem = outItem; - rv = ssl3_AppendNumberToItem(&outItem, 0, 2); + /* Leave space for the length of the ciphertext. */ + rv = sslBuffer_Skip(&buf, 2, &lenOffset); if (rv != SECSuccess) { return SECFailure; } + /* Encode the ciphertext in place. */ rv = PK11_Encrypt(encKey, CKM_AES_CBC_PAD, &ivItem, - outItem.data, &len, outItem.len, in, inLen); + SSL_BUFFER_NEXT(&buf), &len, + SSL_BUFFER_SPACE(&buf), in, inLen); + if (rv != SECSuccess) { + return SECFailure; + } + rv = sslBuffer_Skip(&buf, len, NULL); if (rv != SECSuccess) { return SECFailure; } - outItem.data += len; - outItem.len -= len; - - /* Now encode the ciphertext length. */ - rv = ssl3_AppendNumberToItem(&lengthBytesItem, len, 2); + rv = sslBuffer_InsertLength(&buf, lenOffset, 2); if (rv != SECSuccess) { return SECFailure; } - /* MAC the entire output buffer and append the MAC to the end. */ + /* MAC the entire output buffer into the output. */ + PORT_Assert(buf.space - buf.len >= SHA256_LENGTH); rv = ssl_MacBuffer(macKey, CKM_SHA256_HMAC, - out, outItem.data - out, - mac, &macLen, sizeof(mac)); + SSL_BUFFER_BASE(&buf), /* input */ + SSL_BUFFER_LEN(&buf), + SSL_BUFFER_NEXT(&buf), &len, /* output */ + SHA256_LENGTH); if (rv != SECSuccess) { return SECFailure; } - PORT_Assert(macLen == sizeof(mac)); - - rv = ssl3_AppendToItem(&outItem, mac, macLen); + rv = sslBuffer_Skip(&buf, len, NULL); if (rv != SECSuccess) { return SECFailure; } - *outLen = outItem.data - out; + *outLen = SSL_BUFFER_LEN(&buf); return SECSuccess; } @@ -192,75 +192,71 @@ ssl_SelfEncryptUnprotectInt( const PRUint8 *in, unsigned int inLen, PRUint8 *out, unsigned int *outLen, unsigned int maxOutLen) { - unsigned char *encodedKeyName; - unsigned char *iv; - SECItem ivItem = { siBuffer, NULL, 0 }; - SECItem inItem = { siBuffer, (unsigned char *)in, inLen }; - unsigned char *cipherText; - PRUint32 cipherTextLen; - unsigned char *encodedMac; - unsigned char computedMac[SHA256_LENGTH]; - unsigned int computedMacLen; - unsigned int bytesToMac; - SECStatus rv; + sslReader reader = SSL_READER(in, inLen); - rv = ssl3_ConsumeFromItem(&inItem, &encodedKeyName, - SELF_ENCRYPT_KEY_NAME_LEN); + sslReadBuffer encodedKeyNameBuffer = { 0 }; + SECStatus rv = sslRead_Read(&reader, SELF_ENCRYPT_KEY_NAME_LEN, + &encodedKeyNameBuffer); if (rv != SECSuccess) { return SECFailure; } - rv = ssl3_ConsumeFromItem(&inItem, &iv, AES_BLOCK_SIZE); + sslReadBuffer ivBuffer = { 0 }; + rv = sslRead_Read(&reader, AES_BLOCK_SIZE, &ivBuffer); if (rv != SECSuccess) { return SECFailure; } - rv = ssl3_ConsumeNumberFromItem(&inItem, &cipherTextLen, 2); + PRUint64 cipherTextLen = 0; + rv = sslRead_ReadNumber(&reader, 2, &cipherTextLen); if (rv != SECSuccess) { return SECFailure; } - rv = ssl3_ConsumeFromItem(&inItem, &cipherText, cipherTextLen); + sslReadBuffer cipherTextBuffer = { 0 }; + rv = sslRead_Read(&reader, (unsigned int)cipherTextLen, &cipherTextBuffer); if (rv != SECSuccess) { return SECFailure; } - bytesToMac = inItem.data - in; + unsigned int bytesToMac = reader.offset; - rv = ssl3_ConsumeFromItem(&inItem, &encodedMac, SHA256_LENGTH); + sslReadBuffer encodedMacBuffer = { 0 }; + rv = sslRead_Read(&reader, SHA256_LENGTH, &encodedMacBuffer); if (rv != SECSuccess) { return SECFailure; } /* Make sure we're at the end of the block. */ - if (inItem.len) { + if (reader.offset != reader.buf.len) { PORT_SetError(SEC_ERROR_BAD_DATA); return SECFailure; } /* Now that everything is decoded, we can make progress. */ /* 1. Check that we have the right key. */ - if (PORT_Memcmp(keyName, encodedKeyName, SELF_ENCRYPT_KEY_NAME_LEN)) { + if (PORT_Memcmp(keyName, encodedKeyNameBuffer.buf, SELF_ENCRYPT_KEY_NAME_LEN)) { PORT_SetError(SEC_ERROR_NOT_A_RECIPIENT); return SECFailure; } /* 2. Check the MAC */ + unsigned char computedMac[SHA256_LENGTH]; + unsigned int computedMacLen = 0; rv = ssl_MacBuffer(macKey, CKM_SHA256_HMAC, in, bytesToMac, computedMac, &computedMacLen, sizeof(computedMac)); if (rv != SECSuccess) { return SECFailure; } PORT_Assert(computedMacLen == SHA256_LENGTH); - if (NSS_SecureMemcmp(computedMac, encodedMac, computedMacLen) != 0) { + if (NSS_SecureMemcmp(computedMac, encodedMacBuffer.buf, computedMacLen) != 0) { PORT_SetError(SEC_ERROR_BAD_DATA); return SECFailure; } /* 3. OK, it verifies, now decrypt. */ - ivItem.data = iv; - ivItem.len = AES_BLOCK_SIZE; + SECItem ivItem = { siBuffer, (unsigned char *)ivBuffer.buf, AES_BLOCK_SIZE }; rv = PK11_Decrypt(encKey, CKM_AES_CBC_PAD, &ivItem, - out, outLen, maxOutLen, cipherText, cipherTextLen); + out, outLen, maxOutLen, cipherTextBuffer.buf, cipherTextLen); if (rv != SECSuccess) { return SECFailure; } @@ -269,6 +265,17 @@ ssl_SelfEncryptUnprotectInt( } #endif +/* Predict the size of the encrypted data, including padding */ +unsigned int +ssl_SelfEncryptGetProtectedSize(unsigned int inLen) +{ + return SELF_ENCRYPT_KEY_NAME_LEN + + AES_BLOCK_SIZE + + 2 + + ((inLen / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE + /* Padded */ + SHA256_LENGTH; +} + SECStatus ssl_SelfEncryptProtect( sslSocket *ss, const PRUint8 *in, unsigned int inLen, |