Skip to content

Commit bef5410

Browse files
committed
CHANGE: deprecated chacha20, chacha20poly1305 and poly1305 natives are now completely removed
1 parent 03ecaa1 commit bef5410

File tree

5 files changed

+372
-328
lines changed

5 files changed

+372
-328
lines changed

make/rebol3.nest

+1
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,7 @@ include-deprecated-cipher-chacha20: [
508508
include: %src/include/deprecated/
509509
core-files: %core/deprecated/u-chacha20.c
510510
core-files: %core/deprecated/u-poly1305.c
511+
core-files: %core/deprecated/n-crypt-chacha.c
511512
]
512513

513514
include-rsa: [

src/core/deprecated/n-crypt-chacha.c

+364
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,364 @@
1+
/***********************************************************************
2+
**
3+
** REBOL [R3] Language Interpreter and Run-time Environment
4+
**
5+
** Copyright 2012 REBOL Technologies
6+
** Copyright 2012-2021 Rebol Open Source Contributors
7+
** REBOL is a trademark of REBOL Technologies
8+
**
9+
** Licensed under the Apache License, Version 2.0 (the "License");
10+
** you may not use this file except in compliance with the License.
11+
** You may obtain a copy of the License at
12+
**
13+
** http://www.apache.org/licenses/LICENSE-2.0
14+
**
15+
** Unless required by applicable law or agreed to in writing, software
16+
** distributed under the License is distributed on an "AS IS" BASIS,
17+
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
** See the License for the specific language governing permissions and
19+
** limitations under the License.
20+
**
21+
************************************************************************
22+
**
23+
** Module: n-crypt-aes.c
24+
** Summary: native functions for old AES code
25+
** Section: natives
26+
** Author: Oldes, Cyphre
27+
** Notes:
28+
**
29+
***********************************************************************/
30+
31+
#include "sys-core.h"
32+
33+
#ifdef INCLUDE_CHACHA20POLY1305_DEPRECATED
34+
#include "sys-chacha20.h"
35+
#include "sys-poly1305.h"
36+
#endif
37+
38+
39+
/***********************************************************************
40+
**
41+
*/ REBNATIVE(chacha20)
42+
/*
43+
// chacha20: native [
44+
// "Encrypt/decrypt data using ChaCha20 algorithm. Returns stream cipher context handle or encrypted/decrypted data."
45+
// ctx [handle! binary!] "ChaCha20 handle and or binary key for initialization (16 or 32 bytes)"
46+
// /init
47+
// nonce [binary!] "Initialization nonce (IV) - 8 or 12 bytes."
48+
// count [integer!] "A 32-bit block count parameter"
49+
// /aad sequence [integer!] "Sequence number used with /init to modify nonce"
50+
// /stream
51+
// data [binary!] "Data to encrypt/decrypt."
52+
// /into
53+
// out [binary!] "Output buffer (NOT YET IMPLEMENTED)"
54+
// ]
55+
***********************************************************************/
56+
{
57+
#ifndef INCLUDE_CHACHA20POLY1305_DEPRECATED
58+
Trap0(RE_FEATURE_NA);
59+
#else
60+
REBVAL *val_ctx = D_ARG(1);
61+
REBOOL ref_init = D_REF(2);
62+
REBVAL *val_nonce = D_ARG(3);
63+
REBVAL *val_counter = D_ARG(4);
64+
REBOOL ref_aad = D_REF(5);
65+
REBVAL *val_sequence = D_ARG(6);
66+
REBOOL ref_stream = D_REF(7);
67+
REBVAL *val_data = D_ARG(8);
68+
REBOOL ref_into = D_REF(9);
69+
70+
if(ref_into)
71+
Trap0(RE_FEATURE_NA);
72+
73+
REBINT len;
74+
REBU64 sequence;
75+
76+
if (IS_BINARY(val_ctx)) {
77+
len = VAL_LEN(val_ctx);
78+
if (!(len == 32 || len == 16)) {
79+
//printf("ChaCha20 key must be of size 32 or 16 bytes! Is: %i\n", len);
80+
Trap1(RE_INVALID_DATA, val_ctx);
81+
return R_NONE;
82+
}
83+
REBYTE *bin_key = VAL_BIN_AT(val_ctx);
84+
85+
MAKE_HANDLE(val_ctx, SYM_CHACHA20);
86+
chacha20_keysetup((chacha20_ctx*)VAL_HANDLE_CONTEXT_DATA(val_ctx), bin_key, len);
87+
}
88+
else {
89+
if (NOT_VALID_CONTEXT_HANDLE(val_ctx, SYM_CHACHA20)) {
90+
Trap0(RE_INVALID_HANDLE);
91+
return R_NONE; // avoid wornings later
92+
}
93+
}
94+
95+
if (ref_init) {
96+
// initialize nonce with counter
97+
98+
len = VAL_LEN(val_nonce);
99+
100+
if (!(len == 12 || len == 8)) {
101+
Trap1(RE_INVALID_DATA, val_nonce);
102+
return R_NONE;
103+
}
104+
105+
sequence = (ref_aad) ? VAL_INT64(val_sequence) : 0;
106+
chacha20_ivsetup((chacha20_ctx*)VAL_HANDLE_CONTEXT_DATA(val_ctx), VAL_BIN_AT(val_nonce), len, VAL_INT64(val_counter), (u8 *)&sequence);
107+
}
108+
109+
if (ref_stream) {
110+
111+
len = VAL_LEN(val_data);
112+
if (len == 0) return R_NONE;
113+
114+
REBYTE *data = VAL_BIN_AT(val_data);
115+
REBSER *binaryOut = Make_Binary(len);
116+
117+
chacha20_encrypt(
118+
(chacha20_ctx *)VAL_HANDLE_CONTEXT_DATA(val_ctx),
119+
(const uint8_t*)data,
120+
( uint8_t*)BIN_DATA(binaryOut),
121+
len
122+
);
123+
124+
SET_BINARY(val_ctx, binaryOut);
125+
VAL_TAIL(val_ctx) = len;
126+
127+
}
128+
#endif // EXCLUDE_CHACHA20POLY1305
129+
return R_ARG1;
130+
}
131+
132+
133+
134+
/***********************************************************************
135+
**
136+
*/ REBNATIVE(poly1305)
137+
/*
138+
// poly1305: native [
139+
// "poly1305 message-authentication"
140+
// ctx [handle! binary!] "poly1305 handle and or binary key for initialization (32 bytes)"
141+
// /update data [binary!] "data to authenticate"
142+
// /finish "finish data stream and return raw result as a binary"
143+
// /verify "finish data stream and compare result with expected result (MAC)"
144+
// mac [binary!] "16 bytes of verification MAC"
145+
// ]
146+
***********************************************************************/
147+
{
148+
#ifndef INCLUDE_CHACHA20POLY1305_DEPRECATED
149+
Trap0(RE_FEATURE_NA);
150+
#else
151+
REBVAL *val_ctx = D_ARG(1);
152+
REBOOL ref_update = D_REF(2);
153+
REBVAL *val_data = D_ARG(3);
154+
REBOOL ref_finish = D_REF(4);
155+
REBOOL ref_verify = D_REF(5);
156+
REBVAL *val_mac = D_ARG(6);
157+
158+
REBVAL *ret = D_RET;
159+
// REBSER *ctx_ser;
160+
REBINT len;
161+
// REBCNT i;
162+
REBYTE mac[16];
163+
164+
if (IS_BINARY(val_ctx)) {
165+
len = VAL_LEN(val_ctx);
166+
if (len < POLY1305_KEYLEN) {
167+
Trap1(RE_INVALID_DATA, val_ctx);
168+
return R_NONE;
169+
}
170+
171+
REBYTE *bin_key = VAL_BIN_AT(val_ctx);
172+
173+
MAKE_HANDLE(val_ctx, SYM_POLY1305);
174+
poly1305_init((poly1305_context*)VAL_HANDLE_CONTEXT_DATA(val_ctx), bin_key);
175+
}
176+
else {
177+
if (NOT_VALID_CONTEXT_HANDLE(val_ctx, SYM_POLY1305)) {
178+
Trap0(RE_INVALID_HANDLE);
179+
}
180+
}
181+
182+
if (ref_update) {
183+
poly1305_update((poly1305_context*)VAL_HANDLE_CONTEXT_DATA(val_ctx), VAL_BIN_AT(val_data), VAL_LEN(val_data));
184+
}
185+
186+
if (ref_finish) {
187+
SET_BINARY(ret, Make_Series(16, 1, FALSE));
188+
VAL_TAIL(ret) = 16;
189+
poly1305_finish((poly1305_context*)VAL_HANDLE_CONTEXT_DATA(val_ctx), VAL_BIN(ret));
190+
return R_RET;
191+
}
192+
193+
if (ref_verify) {
194+
if (VAL_LEN(val_mac) != POLY1305_TAGLEN)
195+
return R_FALSE; // or error?
196+
CLEARS(mac);
197+
poly1305_finish((poly1305_context*)VAL_HANDLE_CONTEXT_DATA(val_ctx), mac);
198+
return (poly1305_verify(VAL_BIN_AT(val_mac), mac)) ? R_TRUE : R_FALSE;
199+
}
200+
201+
#endif // EXCLUDE_CHACHA20POLY1305
202+
return R_ARG1;
203+
}
204+
205+
/***********************************************************************
206+
**
207+
*/ REBNATIVE(chacha20poly1305)
208+
/*
209+
// chacha20poly1305: native [
210+
// "..."
211+
// ctx [none! handle!]
212+
// /init
213+
// local-key [binary!]
214+
// local-iv [binary!]
215+
// remote-key [binary!]
216+
// remote-iv [binary!]
217+
// /encrypt
218+
// data-out [binary!]
219+
// aad-out [binary!]
220+
// /decrypt
221+
// data-in [binary!]
222+
// aad-in [binary!]
223+
// ]
224+
***********************************************************************/
225+
{
226+
#ifndef INCLUDE_CHACHA20POLY1305_DEPRECATED
227+
Trap0(RE_FEATURE_NA);
228+
#else
229+
REBVAL *val_ctx = D_ARG(1);
230+
REBOOL ref_init = D_REF(2);
231+
REBVAL *val_local_key = D_ARG(3);
232+
REBVAL *val_local_iv = D_ARG(4);
233+
REBVAL *val_remote_key = D_ARG(5);
234+
REBVAL *val_remote_iv = D_ARG(6);
235+
REBOOL ref_encrypt = D_REF(7);
236+
REBVAL *val_plain = D_ARG(8);
237+
REBVAL *val_local_aad = D_ARG(9);
238+
REBOOL ref_decrypt = D_REF(10);
239+
REBVAL *val_cipher = D_ARG(11);
240+
REBVAL *val_remote_aad = D_ARG(12);
241+
242+
REBSER *ctx_ser;
243+
REBINT len;
244+
chacha20poly1305_ctx *chacha;
245+
unsigned char poly1305_key[POLY1305_KEYLEN];
246+
size_t aad_size;
247+
REBU64 sequence = 0;
248+
249+
if (ref_init) {
250+
MAKE_HANDLE(val_ctx, SYM_CHACHA20POLY1305);
251+
252+
chacha = (chacha20poly1305_ctx*)VAL_HANDLE_CONTEXT_DATA(val_ctx);
253+
len = VAL_LEN(val_local_key);
254+
if (!(len == 32 || len == 16))
255+
Trap1(RE_INVALID_DATA, val_local_key);
256+
chacha20_keysetup(&chacha->local_chacha, VAL_BIN_AT(val_local_key), len);
257+
len = VAL_LEN(val_remote_key);
258+
if (!(len == 32 || len == 16))
259+
Trap1(RE_INVALID_DATA, val_remote_key);
260+
chacha20_keysetup(&chacha->remote_chacha, VAL_BIN_AT(val_remote_key), len);
261+
262+
len = VAL_LEN(val_local_iv);
263+
if (!(len == 12 || len == 8))
264+
Trap1(RE_INVALID_DATA, val_local_iv);
265+
chacha20_ivsetup(&chacha->local_chacha, VAL_BIN_AT(val_local_iv), len, 1, (u8 *)&sequence);
266+
memcpy(chacha->local_iv, VAL_BIN_AT(val_local_iv), len);
267+
268+
len = VAL_LEN(val_remote_iv);
269+
if (!(len == 12 || len == 8))
270+
Trap1(RE_INVALID_DATA, val_remote_iv);
271+
chacha20_ivsetup(&chacha->remote_chacha, VAL_BIN_AT(val_remote_iv), len, 1, (u8 *)&sequence);
272+
memcpy(chacha->remote_iv, VAL_BIN_AT(val_remote_iv), len);
273+
return R_ARG1;
274+
}
275+
276+
if (NOT_VALID_CONTEXT_HANDLE(val_ctx, SYM_CHACHA20POLY1305)) {
277+
Trap0(RE_INVALID_HANDLE);
278+
return R_NONE;
279+
}
280+
chacha = (chacha20poly1305_ctx*)VAL_HANDLE_CONTEXT_DATA(val_ctx);
281+
282+
if (ref_encrypt) {
283+
chacha20_ivsetup(&chacha->local_chacha, chacha->local_iv, 12, 1, VAL_BIN_AT(val_local_aad));
284+
chacha20_poly1305_key(&chacha->local_chacha, poly1305_key);
285+
//puts("poly1305_key:"); Dump_Bytes(poly1305_key, POLY1305_KEYLEN);
286+
287+
len = VAL_LEN(val_plain) + POLY1305_TAGLEN;
288+
ctx_ser = Make_Series(len, (REBCNT)1, FALSE);
289+
290+
// AEAD
291+
// sequence number (8 bytes)
292+
// content type (1 byte)
293+
// version (2 bytes)
294+
// length (2 bytes)
295+
unsigned char aad[13];
296+
aad_size = sizeof(aad);
297+
// unsigned char *sequence = aad;
298+
299+
chacha20_poly1305_aead(&chacha->local_chacha, VAL_BIN_AT(val_plain), (REBCNT)len-POLY1305_TAGLEN, VAL_BIN_AT(val_local_aad), VAL_LEN(val_local_aad), poly1305_key, ctx_ser->data);
300+
301+
//chacha->local_sequence++;
302+
303+
SERIES_TAIL(ctx_ser) = len;
304+
SET_BINARY(val_ctx, ctx_ser);
305+
return R_ARG1;
306+
}
307+
308+
if (ref_decrypt) {
309+
static unsigned char zeropad[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
310+
unsigned char trail[16];
311+
unsigned char mac_tag[POLY1305_TAGLEN];
312+
313+
chacha20_ivsetup(&chacha->remote_chacha, chacha->remote_iv, 12, 1, VAL_BIN_AT(val_remote_aad));
314+
315+
len = VAL_LEN(val_cipher) - POLY1305_TAGLEN;
316+
if (len <= 0)
317+
return R_NONE;
318+
319+
ctx_ser = Make_Series(len, (REBCNT)1, FALSE);
320+
321+
//puts("\nDECRYPT:");
322+
323+
chacha20_encrypt(&chacha->remote_chacha, VAL_BIN_AT(val_cipher), ctx_ser->data, len);
324+
//chacha_encrypt_bytes(&chacha->remote_chacha, VAL_BIN_AT(val_cipher), ctx_ser->data, len);
325+
chacha20_poly1305_key(&chacha->remote_chacha, poly1305_key);
326+
//puts("poly1305_key:"); Dump_Bytes(poly1305_key, POLY1305_KEYLEN);
327+
328+
poly1305_context aead_ctx;
329+
poly1305_init(&aead_ctx, poly1305_key);
330+
331+
aad_size = VAL_LEN(val_remote_aad);
332+
poly1305_update(&aead_ctx, VAL_BIN_AT(val_remote_aad), aad_size);
333+
int rem = aad_size % 16;
334+
if (rem)
335+
poly1305_update(&aead_ctx, zeropad, 16 - rem);
336+
//puts("update:"); Dump_Bytes(VAL_BIN_AT(val_cipher), len);
337+
poly1305_update(&aead_ctx, VAL_BIN_AT(val_cipher), len);
338+
rem = len % 16;
339+
if (rem)
340+
poly1305_update(&aead_ctx, zeropad, 16 - rem);
341+
342+
U32TO8_LE(&trail[0], aad_size == 5 ? 5 : 13);
343+
*(int *)&trail[4] = 0;
344+
U32TO8_LE(&trail[8], len);
345+
*(int *)&trail[12] = 0;
346+
347+
//puts("trail:"); Dump_Bytes(trail, 16);
348+
349+
poly1305_update(&aead_ctx, trail, 16);
350+
poly1305_finish(&aead_ctx, mac_tag);
351+
352+
if (!poly1305_verify(mac_tag, VAL_BIN_TAIL(val_cipher) - POLY1305_TAGLEN)) {
353+
//puts("MAC verification failed!");
354+
return R_NONE;
355+
}
356+
357+
//puts("mac result:"); Dump_Bytes(mac_tag, POLY1305_TAGLEN);
358+
359+
SERIES_TAIL(ctx_ser) = len;
360+
SET_BINARY(val_ctx, ctx_ser);
361+
}
362+
#endif // EXCLUDE_CHACHA20POLY1305
363+
return R_ARG1;
364+
}

0 commit comments

Comments
 (0)