Skip to content

Commit b1a1dff

Browse files
committed
Added working test for chacha20poly1305
1 parent 6cbf8db commit b1a1dff

File tree

4 files changed

+89
-57
lines changed

4 files changed

+89
-57
lines changed

scripts/build_ffi.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -642,19 +642,19 @@ def build_ffi(local_wolfssl, features):
642642
if features["CHACHA20_POLY1305"]:
643643
cdef += """
644644
typedef struct { ...; } ChaChaPoly_Aead;
645-
int wc_ChaCha20Poly1305_Encrypt(const byte inKey, const byte inIV, const byte* inAAD,
645+
int wc_ChaCha20Poly1305_Encrypt(const byte* inKey, const byte* inIV, const byte* inAAD,
646646
word32 inAADLen, const byte* inPlaintext, word32 inPlaintextLen, byte* outCiphertext,
647-
byte outAuthTag);
648-
int wc_ChaCha20Poly1305_Decrypt( const byte inKey, const byte inIV, const byte* inAAD,
647+
byte* outAuthTag);
648+
int wc_ChaCha20Poly1305_Decrypt(const byte* inKey, const byte* inIV, const byte* inAAD,
649649
word32 inAADLen, const byte* inCiphertext, word32 inCiphertextLen,
650-
const byte inAuthTag, byte* outPlaintext);
650+
const byte* inAuthTag, byte* outPlaintext);
651651
int wc_ChaCha20Poly1305_UpdateAad(ChaChaPoly_Aead* aead,
652652
const byte* inAAD, word32 inAADLen);
653-
int wc_ChaCha20Poly1305_Init(ChaChaPoly_Aead* aead, const byte inKey, const byte inIV,
653+
int wc_ChaCha20Poly1305_Init(ChaChaPoly_Aead* aead, const byte* inKey, const byte* inIV,
654654
int isEncrypt);
655655
int wc_ChaCha20Poly1305_UpdateData(ChaChaPoly_Aead* aead,
656656
const byte* inData, byte* outData, word32 dataLen);
657-
int wc_ChaCha20Poly1305_Final(byte*, word32);
657+
int wc_ChaCha20Poly1305_Final(ChaChaPoly_Aead* aead, byte* outTag);
658658
int wc_ChaCha20Poly1305_CheckTag(const byte* authtag, const byte* authTagChk);
659659
"""
660660

tests/test_chacha20poly1305.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
2+
# test_aesgcmstream.py
3+
#
4+
# Copyright (C) 2022 wolfSSL Inc.
5+
#
6+
# This file is part of wolfSSL. (formerly known as CyaSSL)
7+
#
8+
# wolfSSL is free software; you can redistribute it and/or modify
9+
# it under the terms of the GNU General Public License as published by
10+
# the Free Software Foundation; either version 2 of the License, or
11+
# (at your option) any later version.
12+
#
13+
# wolfSSL is distributed in the hope that it will be useful,
14+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
# GNU General Public License for more details.
17+
#
18+
# You should have received a copy of the GNU General Public License
19+
# along with this program; if not, write to the Free Software
20+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
21+
22+
# pylint: disable=redefined-outer-name
23+
24+
from wolfcrypt._ffi import lib as _lib
25+
26+
if _lib.CHACHA20_POLY1305_ENABLED:
27+
from collections import namedtuple
28+
import pytest
29+
from wolfcrypt.utils import t2b
30+
from wolfcrypt.exceptions import WolfCryptError
31+
from binascii import hexlify as b2h, unhexlify as h2b
32+
from wolfcrypt.ciphers import ChaCha20Poly1305
33+
34+
def test_encrypt_decrypt():
35+
key = "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f"
36+
key = h2b(key)
37+
iv = "07000000404142434445464748" #Chnage from C test
38+
iv = h2b(iv)
39+
aad = "50515253c0c1c2c3c4c5c6c7" #Change from C test
40+
aad = h2b(aad)
41+
plaintext1 = "4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e"
42+
plaintext1 = h2b(plaintext1)
43+
cipher1 = "d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116"
44+
authTag = "1ae10b594f09e26a7e902ecbd0600691"
45+
chacha = ChaCha20Poly1305(key, iv, aad)
46+
generatedChipherText, generatedAuthTag = chacha.encrypt(plaintext1)
47+
assert h2b(cipher1) == generatedChipherText
48+
assert h2b(authTag) == generatedAuthTag
49+
chachadec = ChaCha20Poly1305(key, iv, aad)
50+
generatedPlaintextdec = chachadec.decrypt(generatedAuthTag, generatedChipherText)#takes in the generated authtag made by encrypt and decrypts and produces the plaintext
51+
assert generatedPlaintextdec == t2b("Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.")

tests/test_ciphers.py

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,6 @@
3535
if _lib.AES_ENABLED:
3636
from wolfcrypt.ciphers import Aes
3737

38-
if _lib.CHACHA20_POLY1305_ENABLED:
39-
from wolfcrypt.ciphers import ChaCha20Poly1305
40-
4138
if _lib.CHACHA_ENABLED:
4239
from wolfcrypt.ciphers import ChaCha
4340

@@ -76,14 +73,6 @@ def vectors():
7673
ciphertext=h2b("959492575f4281532ccc9d4677a233cb"),
7774
ciphertext_ctr = h2b('287528ddf484b1055debbe751eb52b8a')
7875
)
79-
if _lib.CHACHA20_POLY1305_ENABLED:
80-
vectorArray[ChaCha20Poly1305]=TestVector(
81-
key="0123456789abcdef",
82-
iv="1234567890abcdef",
83-
plaintext=t2b("now is the time "),
84-
ciphertext=h2b("959492575f4281532ccc9d4677a233cb"),
85-
ciphertext_ctr = h2b('287528ddf484b1055debbe751eb52b8a')
86-
)
8776
if _lib.CHACHA_ENABLED:
8877
vectorArray[ChaCha]=TestVector(
8978
key="0123456789abcdef01234567890abcdef",
@@ -96,7 +85,6 @@ def vectors():
9685
plaintext=t2b("Now is the time for all "),
9786
ciphertext=h2b("43a0297ed184f80e8964843212d508981894157487127db0")
9887
)
99-
10088
if _lib.RSA_ENABLED:
10189
vectorArray[RsaPublic]=TestVector(
10290
key=h2b(
@@ -336,20 +324,6 @@ def test_chacha_enc_dec(chacha_obj):
336324
dec = chacha_obj.decrypt(cyt)
337325
assert plaintext == dec
338326

339-
if _lib.CHACHA20_POLY1305_ENABLED:
340-
@pytest.fixture
341-
def chacha20_poly1305_obj(vectors):
342-
r = ChaCha20Poly1305(vectors[ChaCha20Poly1305].key, vectors[ChaCha20Poly1305].iv)
343-
return r
344-
345-
@pytest.fixture
346-
def test_chacha20_poly1305_enc_dec(chacha20_poly1305_obj):
347-
plaintext = t2b("Everyone gets Friday off.")
348-
cyt = chacha20_poly1305_obj.encrypt(plaintext)
349-
dec = chacha20_poly1305_obj.decrypt(cyt)
350-
assert plaintext == dec
351-
352-
353327
if _lib.RSA_ENABLED:
354328
@pytest.fixture
355329
def rsa_private(vectors):

wolfcrypt/ciphers.py

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -432,27 +432,29 @@ class ChaCha20Poly1305(object):
432432
"""
433433
block_size = 16
434434
_key_sizes = [16, 24, 32]
435-
_native_type = "ChaCha *"
436-
_aad = bytes()
435+
_native_type = "ChaChaPoly_Aead *"
436+
_aad = None
437437
_tag_bytes = 16
438438
_mode = None
439-
generatedCipherText = bytes()
440-
generatedPlainText = bytes()
439+
_key = bytes()
440+
_IV = bytes()
441441

442-
def __init__(self, key, IV, isEncrypt):
442+
def __init__(self, key, IV, aad, tag_bytes=16):
443443
"""
444444
tag_bytes is the number of bytes to use for the authentication tag during encryption
445445
"""
446-
key = t2b(key)
447-
IV = t2b(IV)
448-
isEncrypt = True
446+
#key = t2b(key)
447+
#IV = t2b(IV)
448+
#aad = t2b(aad)
449+
self._key = key
450+
self._IV = IV
451+
self._aad = aad
449452
if len(key) not in self._key_sizes:
450453
raise ValueError("key must be %s in length, not %d" %
451454
(self._key_sizes, len(key)))
452455
self._native_object = _ffi.new(self._native_type)
453-
_lib.wc_AesInit(self._native_object, _ffi.NULL, -2)
454-
ret = _lib.wc_ChaCha20Poly1305_Init(self._native_object, self._aad, len(self._aad),
455-
key, len(key), IV, len(IV), isEncrypt)
456+
self._mode = None
457+
ret = _lib.wc_ChaCha20Poly1305_Init(self._native_object, key, IV, 1)
456458
if ret < 0:
457459
raise WolfCryptError("Init error (%d)" % ret)
458460

@@ -467,41 +469,45 @@ def set_aad(self, data):
467469
def get_aad(self):
468470
return self._aad
469471

470-
def encrypt(self, data):
472+
def encrypt(self, inPlainText):
471473
"""
472474
Add more data to the encryption stream
473475
"""
474-
data = t2b(data)
475-
aad = bytes()
476+
477+
#inPlainText = t2b(inPlainText)
476478
if self._mode is None:
477479
self._mode = _ENCRYPTION
478480
aad = self._aad
479481
elif self._mode == _DECRYPTION:
480482
raise WolfCryptError("Class instance already in use for decryption")
481-
self._buf = _ffi.new("byte[%d]" % (len(data)))
482-
ret = _lib.wc_ChaCha20Poly1305_UpdateData(self._native_type, aad, len(aad))
483+
outGeneratedCipherText = _ffi.new("byte[%d]" % (len(inPlainText))) #array of output data (inPlainText) in bytes
484+
outGeneratedAuthTag = _ffi.new("byte[%d]" % self._tag_bytes)
485+
ret = _lib.wc_ChaCha20Poly1305_Encrypt(self._key, self._IV, aad, len(aad),
486+
inPlainText, len(inPlainText),
487+
outGeneratedCipherText,
488+
outGeneratedAuthTag) #outputs are generatedCipherText and generatedAuthTag
489+
483490
if ret < 0:
484491
raise WolfCryptError("Decryption error (%d)" % ret)
485-
return bytes(self._buf)
492+
return bytes(outGeneratedCipherText), bytes(outGeneratedAuthTag)
486493

487-
def decrypt(self, data):
494+
def decrypt(self, inGeneratedAuthTag, inGeneratedCipher):#plain text is the output and should be hello world
488495
"""
489496
Add more data to the decryption stream
490497
"""
491-
aad = bytes()
492-
data = t2b(data)
498+
inGeneratedCipher = t2b(inGeneratedCipher) #Should be the chipher from encrypt
493499
if self._mode is None:
494500
self._mode = _DECRYPTION
495501
aad = self._aad
496502
elif self._mode == _ENCRYPTION:
497503
raise WolfCryptError("Class instance already in use for decryption")
498-
self._buf = _ffi.new("byte[%d]" % (len(data)))
499-
ret = _lib.wc_ChaCha20Poly1305_Decrypt(self._key, self_IV, aad, len(aad),
500-
generatedCipherText, len(generatedCipherText),
501-
authTag, generatedPlainText)
504+
outPlainText= _ffi.new("byte[%d]" % (len(inGeneratedCipher)))#unsure what to put here
505+
ret = _lib.wc_ChaCha20Poly1305_Decrypt(self._key, self._IV, aad, len(self._aad),
506+
inGeneratedCipher, len(inGeneratedCipher),
507+
inGeneratedAuthTag, outPlainText)
502508
if ret < 0:
503509
raise WolfCryptError("Decryption error (%d)" % ret)
504-
return bytes(self._buf)
510+
return bytes(outPlainText) # prettysure outplain text is the output
505511

506512
def checkTag(self, authTag):
507513
"""
@@ -530,6 +536,7 @@ def final(self, authTag=None):
530536
if authTag is None:
531537
raise WolfCryptError("authTag parameter required")
532538
authTag = t2b(authTag)
539+
self._native_object = _ffi.new(self._native_type)
533540
ret = _lib.wc_ChaCha20Poly1305_Final(self._native_type, authTag)
534541
if ret < 0:
535542
raise WolfCryptError("Decryption error (%d)" % ret)

0 commit comments

Comments
 (0)