Skip to content

Commit

Permalink
FEAT: included CHACHA20 cipher with possibility to set initial block …
Browse files Browse the repository at this point in the history
…counter
  • Loading branch information
Oldes committed Jan 25, 2022
1 parent 84fffcb commit d4bd521
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 10 deletions.
2 changes: 1 addition & 1 deletion make/rebol3.nest
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ include-cryptography: [
:include-cipher-camelia
:include-cipher-cbc
;:include-cipher-gcm
;:include-cipher-chacha20
:include-cipher-chacha20
;:include-cipher-chachapoly
:include-cipher-chacha20-deprecated
:include-cipher-aes-deprecated
Expand Down
10 changes: 8 additions & 2 deletions src/core/mbedtls/cipher.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,9 +386,15 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
#if defined(MBEDTLS_CHACHA20_C)
if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 )
{
unsigned int counter = 0U; /* Initial counter value */
if (iv_len == 16) {
counter = ((unsigned int)iv[12] << 32)
| ((unsigned int)iv[13] << 16)
| ((unsigned int)iv[14] << 8)
| (unsigned int)iv[15];
}
if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx,
iv,
0U ) ) /* Initial counter value */
iv, counter) )
{
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
Expand Down
19 changes: 12 additions & 7 deletions src/core/p-crypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,13 @@ static REBOOL init_crypt_algorithm(CRYPT_CTX *ctx, REBVAL *val) {

err = mbedtls_cipher_set_iv(&ctx->cipher, ctx->IV, 16);
if (err) goto failed;

err = mbedtls_cipher_reset(&ctx->cipher);
if (err) goto failed;

ctx->buffer = Make_Binary(256);
// protect the buffer using KEEP, because it is not accesible from any other Rebol value!
// buffer is extended when needed.
// protected using KEEP, because it is not accesible from any real Rebol value!
KEEP_SERIES(ctx->buffer, "crypt");

return TRUE;
Expand Down Expand Up @@ -208,6 +210,7 @@ static REBOOL init_crypt_algorithm(CRYPT_CTX *ctx, REBVAL *val) {
REBSER *bin;
REBSER *out;
REBCNT len;
REBCNT ofs, blk;
REBINT err;
size_t olen = 0;
CRYPT_CTX *ctx = NULL;
Expand Down Expand Up @@ -253,8 +256,9 @@ static REBOOL init_crypt_algorithm(CRYPT_CTX *ctx, REBVAL *val) {
Expand_Series(bin, AT_TAIL, len);
// reset the tail (above expand modifies it!)
SERIES_TAIL(bin) = olen;
REBCNT ofs = 0;
REBCNT blk = mbedtls_cipher_get_block_size(&ctx->cipher);
ofs = 0;
blk = mbedtls_cipher_get_block_size(&ctx->cipher);
if (blk == 1) blk = len; // MBEDTLS_MODE_STREAM, so we can process all data at once
REBYTE *p = VAL_BIN_AT(arg1);
if (ctx->unprocessed_len > 0) {
if (ctx->unprocessed_len > blk) abort();
Expand Down Expand Up @@ -300,21 +304,22 @@ static REBOOL init_crypt_algorithm(CRYPT_CTX *ctx, REBVAL *val) {
break;
case A_UPDATE:
if (ctx->unprocessed_len > 0) {
REBCNT ofs = 0;
REBCNT blk = mbedtls_cipher_get_block_size(&ctx->cipher);
ofs = 0;
blk = mbedtls_cipher_get_block_size(&ctx->cipher);
olen = SERIES_TAIL(bin);
Expand_Series(bin, AT_TAIL, blk);
// reset the tail (above expand modifies it!)
SERIES_TAIL(bin) = olen;

if (ctx->unprocessed_len > blk) abort();
REBCNT n = blk - ctx->unprocessed_len;
len = blk - ctx->unprocessed_len;
// pad with zeros...
memset(ctx->unprocessed_data + ctx->unprocessed_len, 0, n);
memset(ctx->unprocessed_data + ctx->unprocessed_len, 0, len);
err = mbedtls_cipher_update(&ctx->cipher, ctx->unprocessed_data, blk, BIN_TAIL(bin), &olen);
SERIES_TAIL(bin) += olen;
ctx->unprocessed_len = 0;
}
//TODO... do we really want to finish on update?!
mbedtls_cipher_finish(&ctx->cipher, BIN_TAIL(bin), &olen);
SERIES_TAIL(bin) += olen;
break;
Expand Down
84 changes: 84 additions & 0 deletions src/tests/units/crypt-port-test.r3
Original file line number Diff line number Diff line change
Expand Up @@ -295,4 +295,88 @@ foreach [cipher tests] monte-carlo-cbc-tests [
===end-group===


if find system/catalog/ciphers 'CHACHA20 [
===start-group=== "The ChaCha20 Block Functions from RFC7539"
;https://datatracker.ietf.org/doc/rfc7539/
port: open crypt://CHACHA20

tests: [
#{0000000000000000000000000000000000000000000000000000000000000000}
#{000000000000000000000000} ; the counter is 0
#{00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000}
#{76B8E0ADA0F13D90405D6AE55386BD28BDD219B8A08DED1AA836EFCC8B770DC7DA41597C5157488D7724E03FB8D84A376A43B8F41518A11CC387B669B2EE6586}

#{0000000000000000000000000000000000000000000000000000000000000000}
#{000000000000000000000000 00000001} ; counter is 1
#{00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000}
#{9F07E7BE5551387A98BA977C732D080DCB0F29A048E3656912C6533E32EE7AED29B721769CE64E43D57133B074D839D531ED1F28510AFB45ACE10A1F4B794D6F}

#{0000000000000000000000000000000000000000000000000000000000000000}
#{000000000000000000000000 00000001} ; counter is 1
#{00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000}
#{9F07E7BE5551387A98BA977C732D080DCB0F29A048E3656912C6533E32EE7AED29B721769CE64E43D57133B074D839D531ED1F28510AFB45ACE10A1F4B794D6F}

#{00FF000000000000000000000000000000000000000000000000000000000000}
#{000000000000000000000000 00000002} ; counter is 2
#{00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000}
#{72D54DFBF12EC44B362692DF94137F328FEA8DA73990265EC1BBBEA1AE9AF0CA13B25AA26CB4A648CB9B9D1BE65B2C0924A66C54D545EC1B7374F4872E99F096}

#{0000000000000000000000000000000000000000000000000000000000000000}
#{000000000000000000000002 00000000} ; counter is 0
#{00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000}
#{C2C64D378CD536374AE204B9EF933FCD1A8B2288B3DFA49672AB765B54EE27C78A970E0E955C14F3A88E741B97C286F75F8FC299E8148362FA198A39531BED6D}
]
n: 1
foreach [key nonce plain cipher] tests [
--test-- join "Test Vector #" n
modify port 'key key
modify port 'iv nonce
--assert cipher = read write port plain
++ n
]

===end-group===

===start-group=== "The ChaCha20 encryption from RFC7539"
;https://datatracker.ietf.org/doc/rfc7539/
port: open crypt://CHACHA20

tests: [
#{0000000000000000000000000000000000000000000000000000000000000000}
#{000000000000000000000000} ; the counter is 0
#{00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000}
#{76B8E0ADA0F13D90405D6AE55386BD28BDD219B8A08DED1AA836EFCC8B770DC7DA41597C5157488D7724E03FB8D84A376A43B8F41518A11CC387B669B2EE6586}

#{0000000000000000000000000000000000000000000000000000000000000001}
#{000000000000000000000002 00000001}
#{416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e7472696275746f7220666f72207075626c69
636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465726e65742d4472616674206f722052464320616e6420616e792073
746174656d656e74206d6164652077697468696e2074686520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572
656420616e20224945544620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c2073746174656d656e
747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c656374726f6e696320636f6d6d756e696361
74696f6e73206d61646520617420616e792074696d65206f7220706c6163652c207768696368206172652061646472657373656420746f}
#{a3fbf07df3fa2fde4f376ca23e82737041605d9f4f4f57bd8cff2c1d4b7955ec2a97948bd3722915c8f3d337f7d370050e9e96d647b7c39f56e031ca5eb6250d
4042e02785ececfa4b4bb5e8ead0440e20b6e8db09d881a7c6132f420e52795042bdfa7773d8a9051447b3291ce1411c680465552aa6c405b7764d5e87bea85a
d00f8449ed8f72d0d662ab052691ca66424bc86d2df80ea41f43abf937d3259dc4b2d0dfb48a6c9139ddd7f76966e928e635553ba76c5c879d7b35d49eb2e62b
0871cdac638939e25e8a1e0ef9d5280fa8ca328b351c3c765989cbcf3daa8b6ccc3aaf9f3979c92b3720fc88dc95ed84a1be059c6499b9fda236e7e818b04b0b
c39c1e876b193bfe5569753f88128cc08aaa9b63d1a16f80ef2554d7189c411f5869ca52c5b83fa36ff216b9c1d30062bebcfd2dc5bce0911934fda79a86f6e6
98ced759c3ff9b6477338f3da4f9cd8514ea9982ccafb341b2384dd902f3d1ab7ac61dd29c6f21ba5b862f3730e37cfdc4fd806c22f221}

#{1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0}
#{000000000000000000000002 0000002A} ; the counter is 42
#{2754776173206272696c6c69672c20616e642074686520736c6974687920746f7665730a446964206779726520616e642067696d626c6520696e2074686520776162653a0a416c6c206d696d737920776572652074686520626f726f676f7665732c0a416e6420746865206d6f6d65207261746873206f757467726162652e}
#{62e6347f95ed87a45ffae7426f27a1df5fb69110044c0d73118effa95b01e5cf166d3df2d721caf9b21e5fb14c616871fd84c54f9d65b283196c7fe4f60553ebf39c6402c42234e32a356b3e764312a61a5532055716ead6962568f87d3f3f7704c6a8d1bcd1bf4d50d6154b6da731b187b58dfd728afa36757a797ac188d1}
]
n: 1
foreach [key nonce plain cipher] tests [
--test-- join "Test Vector #" n
modify port 'key key
modify port 'iv nonce
--assert cipher = read write port plain
++ n
]

===end-group===
] ;end if

~~~end-file~~~

0 comments on commit d4bd521

Please sign in to comment.