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

Unified Diff: nss/lib/freebl/chacha20poly1305.c

Issue 27510015: Support ChaCha20+Poly1305 cipher suites. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/nss/
Patch Set: Fix compilation error, fix typos in function arguments Created 7 years, 2 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 side-by-side diff with in-line comments
Download patch
Index: nss/lib/freebl/chacha20poly1305.c
===================================================================
--- nss/lib/freebl/chacha20poly1305.c (revision 0)
+++ nss/lib/freebl/chacha20poly1305.c (revision 0)
@@ -0,0 +1,102 @@
+#include <string.h>
+#include <stdio.h>
+
+#include "seccomon.h"
+#include "poly1305/poly1305.h"
+#include "chacha20/chacha20.h"
+
+/* Poly1305Do writes the Poly1305 authenticator of the given additional data
+ * and ciphertext to |out|. */
+static void Poly1305Do(unsigned char *out,
+ const unsigned char *ad, size_t adLen,
+ const unsigned char *ciphertext, size_t ciphertextLen,
+ const unsigned char key[32])
+{
+ poly1305_state state;
+ size_t j;
+ unsigned char lengthBytes[8];
+ unsigned int i;
+
+ Poly1305Init(&state, key);
+ j = adLen;
+ for (i = 0; i < sizeof(lengthBytes); i++) {
+ lengthBytes[i] = j;
+ j >>= 8;
+ }
+ Poly1305Update(&state, ad, adLen);
+ Poly1305Update(&state, lengthBytes, sizeof(lengthBytes));
+ j = ciphertextLen;
+ for (i = 0; i < sizeof(lengthBytes); i++) {
+ lengthBytes[i] = j;
+ j >>= 8;
+ }
+ Poly1305Update(&state, ciphertext, ciphertextLen);
+ Poly1305Update(&state, lengthBytes, sizeof(lengthBytes));
+ Poly1305Finish(&state, out);
+}
+
+SECStatus ChaCha20Poly1305_Seal(
+ unsigned char *out,
+ const unsigned char *ad, size_t adLen,
+ const unsigned char *plaintext, size_t plaintextLen,
+ size_t tagLen,
+ const unsigned char key[32],
+ const unsigned char nonce[8])
+{
+ unsigned char block[64];
+ unsigned char tag[16];
+
+ if (tagLen == 0 || tagLen > 16) {
+ return SECFailure;
+ }
+
+ memset(block, 0, 64);
+ // Generate a block of keystream. The first 32 bytes will be the poly1305
+ // key. The remainder of the block is discarded.
+ ChaCha20XOR(block, block, sizeof(block), key, nonce, 0);
+ ChaCha20XOR(out, plaintext, plaintextLen, key, nonce, 1);
+
+ Poly1305Do(tag, ad, adLen, out, plaintextLen, block);
+ memcpy(out + plaintextLen, tag, tagLen);
+
+ return SECSuccess;
+}
+
+SECStatus ChaCha20Poly1305_Open(
+ unsigned char *out,
+ const unsigned char *ad, size_t adLen,
+ const unsigned char *ciphertext, size_t ciphertextLen,
+ size_t tagLen,
+ const unsigned char key[32],
+ const unsigned char nonce[8])
+{
+ unsigned char block[64];
+ unsigned int i;
+ unsigned char macBad;
+ unsigned char mac[16];
+
+ if (tagLen == 0 || tagLen > 16) {
+ return SECFailure;
+ }
+
+ if (ciphertextLen < tagLen) {
+ return SECFailure;
+ }
+
+ memset(block, 0, 64);
+ // Generate a block of keystream. The first 32 bytes will be the poly1305
+ // key. The remainder is used to decrypt the first 32 bytes of plaintext.
+ ChaCha20XOR(block, block, sizeof(block), key, nonce, 0);
+ Poly1305Do(mac, ad, adLen, ciphertext, ciphertextLen - tagLen, block);
+ macBad = 0;
+ for (i = 0; i < tagLen; i++) {
+ macBad |= mac[i] ^ ciphertext[ciphertextLen - tagLen + i];
+ }
+ if (macBad) {
+ return SECFailure;
+ }
+
+ ChaCha20XOR(out, ciphertext, ciphertextLen, key, nonce, 1);
+
+ return SECSuccess;
+}
Property changes on: nss/lib/freebl/chacha20poly1305.c
___________________________________________________________________
Added: svn:eol-style
+ LF

Powered by Google App Engine
This is Rietveld 408576698