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

Side by Side 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: After first review 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 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
9 #include <string.h>
10 #include <stdio.h>
11
12 #include "seccomon.h"
13 #include "secerr.h"
14 #include "poly1305/poly1305.h"
15 #include "chacha20/chacha20.h"
16
17 /* Poly1305Do writes the Poly1305 authenticator of the given additional data
18 * and ciphertext to |out|. */
19 static void
20 Poly1305Do(unsigned char *out,
21 const unsigned char *ad, unsigned int adLen,
22 const unsigned char *ciphertext, unsigned int ciphertextLen,
23 const unsigned char key[32])
24 {
25 poly1305_state state;
26 unsigned int j;
27 unsigned char lengthBytes[8];
28 unsigned int i;
29
30 Poly1305Init(&state, key);
31 j = adLen;
32 for (i = 0; i < sizeof(lengthBytes); i++) {
33 lengthBytes[i] = j;
34 j >>= 8;
35 }
36 Poly1305Update(&state, ad, adLen);
37 Poly1305Update(&state, lengthBytes, sizeof(lengthBytes));
38 j = ciphertextLen;
39 for (i = 0; i < sizeof(lengthBytes); i++) {
40 lengthBytes[i] = j;
41 j >>= 8;
42 }
43 Poly1305Update(&state, ciphertext, ciphertextLen);
44 Poly1305Update(&state, lengthBytes, sizeof(lengthBytes));
45 Poly1305Finish(&state, out);
46 }
47
48 SECStatus
49 ChaCha20Poly1305_Seal(unsigned char *out,
50 const unsigned char *ad, unsigned int adLen,
51 const unsigned char *plaintext, unsigned int plaintextLen,
52 unsigned int tagLen,
53 const unsigned char key[32],
54 const unsigned char nonce[8])
55 {
56 unsigned char block[64];
57 unsigned char tag[16];
58
59 if (tagLen == 0 || tagLen > sizeof(tag)) {
60 PORT_SetError(SEC_ERROR_INPUT_LEN);
61 return SECFailure;
62 }
63
64 memset(block, 0, sizeof(block));
65 // Generate a block of keystream. The first 32 bytes will be the poly1305
66 // key. The remainder of the block is discarded.
67 ChaCha20XOR(block, block, sizeof(block), key, nonce, 0);
68 ChaCha20XOR(out, plaintext, plaintextLen, key, nonce, 1);
69
70 Poly1305Do(tag, ad, adLen, out, plaintextLen, block);
71 memcpy(out + plaintextLen, tag, tagLen);
72
73 return SECSuccess;
74 }
75
76 SECStatus
77 ChaCha20Poly1305_Open(unsigned char *out,
78 const unsigned char *ad, unsigned int adLen,
79 const unsigned char *ciphertext, unsigned int ciphertextLe n,
80 unsigned int tagLen,
81 const unsigned char key[32],
82 const unsigned char nonce[8])
83 {
84 unsigned char block[64];
85 unsigned int i;
86 unsigned char tag[16];
87
88 if (tagLen == 0 || tagLen > sizeof(tag)) {
89 PORT_SetError(SEC_ERROR_INPUT_LEN);
90 return SECFailure;
91 }
92
93 if (ciphertextLen < tagLen) {
94 PORT_SetError(SEC_ERROR_INPUT_LEN);
95 return SECFailure;
96 }
97
98 memset(block, 0, sizeof(block));
99 // Generate a block of keystream. The first 32 bytes will be the poly1305
100 // key. The remainder of the block is discarded.
101 ChaCha20XOR(block, block, sizeof(block), key, nonce, 0);
102 Poly1305Do(tag, ad, adLen, ciphertext, ciphertextLen - tagLen, block);
103 if (NSS_SecureMemcmp(tag, &ciphertext[ciphertextLen - tagLen], tagLen) != 0) {
104 PORT_SetError(SEC_ERROR_BAD_DATA);
105 return SECFailure;
106 }
107
108 ChaCha20XOR(out, ciphertext, ciphertextLen - tagLen, key, nonce, 1);
109
110 return SECSuccess;
111 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698