Added working test for chacha20poly1305

pull/64/head
Jack Tjaden 2024-09-26 13:22:12 -06:00
parent 6cbf8db220
commit b1a1dffbcf
4 changed files with 89 additions and 57 deletions

View File

@ -642,19 +642,19 @@ def build_ffi(local_wolfssl, features):
if features["CHACHA20_POLY1305"]:
cdef += """
typedef struct { ...; } ChaChaPoly_Aead;
int wc_ChaCha20Poly1305_Encrypt(const byte inKey, const byte inIV, const byte* inAAD,
int wc_ChaCha20Poly1305_Encrypt(const byte* inKey, const byte* inIV, const byte* inAAD,
word32 inAADLen, const byte* inPlaintext, word32 inPlaintextLen, byte* outCiphertext,
byte outAuthTag);
int wc_ChaCha20Poly1305_Decrypt( const byte inKey, const byte inIV, const byte* inAAD,
byte* outAuthTag);
int wc_ChaCha20Poly1305_Decrypt(const byte* inKey, const byte* inIV, const byte* inAAD,
word32 inAADLen, const byte* inCiphertext, word32 inCiphertextLen,
const byte inAuthTag, byte* outPlaintext);
const byte* inAuthTag, byte* outPlaintext);
int wc_ChaCha20Poly1305_UpdateAad(ChaChaPoly_Aead* aead,
const byte* inAAD, word32 inAADLen);
int wc_ChaCha20Poly1305_Init(ChaChaPoly_Aead* aead, const byte inKey, const byte inIV,
int wc_ChaCha20Poly1305_Init(ChaChaPoly_Aead* aead, const byte* inKey, const byte* inIV,
int isEncrypt);
int wc_ChaCha20Poly1305_UpdateData(ChaChaPoly_Aead* aead,
const byte* inData, byte* outData, word32 dataLen);
int wc_ChaCha20Poly1305_Final(byte*, word32);
int wc_ChaCha20Poly1305_Final(ChaChaPoly_Aead* aead, byte* outTag);
int wc_ChaCha20Poly1305_CheckTag(const byte* authtag, const byte* authTagChk);
"""

View File

@ -0,0 +1,51 @@
# test_aesgcmstream.py
#
# Copyright (C) 2022 wolfSSL Inc.
#
# This file is part of wolfSSL. (formerly known as CyaSSL)
#
# wolfSSL is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# wolfSSL is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
# pylint: disable=redefined-outer-name
from wolfcrypt._ffi import lib as _lib
if _lib.CHACHA20_POLY1305_ENABLED:
from collections import namedtuple
import pytest
from wolfcrypt.utils import t2b
from wolfcrypt.exceptions import WolfCryptError
from binascii import hexlify as b2h, unhexlify as h2b
from wolfcrypt.ciphers import ChaCha20Poly1305
def test_encrypt_decrypt():
key = "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f"
key = h2b(key)
iv = "07000000404142434445464748" #Chnage from C test
iv = h2b(iv)
aad = "50515253c0c1c2c3c4c5c6c7" #Change from C test
aad = h2b(aad)
plaintext1 = "4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e"
plaintext1 = h2b(plaintext1)
cipher1 = "d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116"
authTag = "1ae10b594f09e26a7e902ecbd0600691"
chacha = ChaCha20Poly1305(key, iv, aad)
generatedChipherText, generatedAuthTag = chacha.encrypt(plaintext1)
assert h2b(cipher1) == generatedChipherText
assert h2b(authTag) == generatedAuthTag
chachadec = ChaCha20Poly1305(key, iv, aad)
generatedPlaintextdec = chachadec.decrypt(generatedAuthTag, generatedChipherText)#takes in the generated authtag made by encrypt and decrypts and produces the plaintext
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.")

View File

@ -35,9 +35,6 @@ if _lib.DES3_ENABLED:
if _lib.AES_ENABLED:
from wolfcrypt.ciphers import Aes
if _lib.CHACHA20_POLY1305_ENABLED:
from wolfcrypt.ciphers import ChaCha20Poly1305
if _lib.CHACHA_ENABLED:
from wolfcrypt.ciphers import ChaCha
@ -76,14 +73,6 @@ def vectors():
ciphertext=h2b("959492575f4281532ccc9d4677a233cb"),
ciphertext_ctr = h2b('287528ddf484b1055debbe751eb52b8a')
)
if _lib.CHACHA20_POLY1305_ENABLED:
vectorArray[ChaCha20Poly1305]=TestVector(
key="0123456789abcdef",
iv="1234567890abcdef",
plaintext=t2b("now is the time "),
ciphertext=h2b("959492575f4281532ccc9d4677a233cb"),
ciphertext_ctr = h2b('287528ddf484b1055debbe751eb52b8a')
)
if _lib.CHACHA_ENABLED:
vectorArray[ChaCha]=TestVector(
key="0123456789abcdef01234567890abcdef",
@ -96,7 +85,6 @@ def vectors():
plaintext=t2b("Now is the time for all "),
ciphertext=h2b("43a0297ed184f80e8964843212d508981894157487127db0")
)
if _lib.RSA_ENABLED:
vectorArray[RsaPublic]=TestVector(
key=h2b(
@ -336,20 +324,6 @@ if _lib.CHACHA_ENABLED:
dec = chacha_obj.decrypt(cyt)
assert plaintext == dec
if _lib.CHACHA20_POLY1305_ENABLED:
@pytest.fixture
def chacha20_poly1305_obj(vectors):
r = ChaCha20Poly1305(vectors[ChaCha20Poly1305].key, vectors[ChaCha20Poly1305].iv)
return r
@pytest.fixture
def test_chacha20_poly1305_enc_dec(chacha20_poly1305_obj):
plaintext = t2b("Everyone gets Friday off.")
cyt = chacha20_poly1305_obj.encrypt(plaintext)
dec = chacha20_poly1305_obj.decrypt(cyt)
assert plaintext == dec
if _lib.RSA_ENABLED:
@pytest.fixture
def rsa_private(vectors):

View File

@ -432,27 +432,29 @@ if _lib.CHACHA20_POLY1305_ENABLED:
"""
block_size = 16
_key_sizes = [16, 24, 32]
_native_type = "ChaCha *"
_aad = bytes()
_native_type = "ChaChaPoly_Aead *"
_aad = None
_tag_bytes = 16
_mode = None
generatedCipherText = bytes()
generatedPlainText = bytes()
_key = bytes()
_IV = bytes()
def __init__(self, key, IV, isEncrypt):
def __init__(self, key, IV, aad, tag_bytes=16):
"""
tag_bytes is the number of bytes to use for the authentication tag during encryption
"""
key = t2b(key)
IV = t2b(IV)
isEncrypt = True
#key = t2b(key)
#IV = t2b(IV)
#aad = t2b(aad)
self._key = key
self._IV = IV
self._aad = aad
if len(key) not in self._key_sizes:
raise ValueError("key must be %s in length, not %d" %
(self._key_sizes, len(key)))
self._native_object = _ffi.new(self._native_type)
_lib.wc_AesInit(self._native_object, _ffi.NULL, -2)
ret = _lib.wc_ChaCha20Poly1305_Init(self._native_object, self._aad, len(self._aad),
key, len(key), IV, len(IV), isEncrypt)
self._mode = None
ret = _lib.wc_ChaCha20Poly1305_Init(self._native_object, key, IV, 1)
if ret < 0:
raise WolfCryptError("Init error (%d)" % ret)
@ -467,41 +469,45 @@ if _lib.CHACHA20_POLY1305_ENABLED:
def get_aad(self):
return self._aad
def encrypt(self, data):
def encrypt(self, inPlainText):
"""
Add more data to the encryption stream
"""
data = t2b(data)
aad = bytes()
#inPlainText = t2b(inPlainText)
if self._mode is None:
self._mode = _ENCRYPTION
aad = self._aad
elif self._mode == _DECRYPTION:
raise WolfCryptError("Class instance already in use for decryption")
self._buf = _ffi.new("byte[%d]" % (len(data)))
ret = _lib.wc_ChaCha20Poly1305_UpdateData(self._native_type, aad, len(aad))
outGeneratedCipherText = _ffi.new("byte[%d]" % (len(inPlainText))) #array of output data (inPlainText) in bytes
outGeneratedAuthTag = _ffi.new("byte[%d]" % self._tag_bytes)
ret = _lib.wc_ChaCha20Poly1305_Encrypt(self._key, self._IV, aad, len(aad),
inPlainText, len(inPlainText),
outGeneratedCipherText,
outGeneratedAuthTag) #outputs are generatedCipherText and generatedAuthTag
if ret < 0:
raise WolfCryptError("Decryption error (%d)" % ret)
return bytes(self._buf)
return bytes(outGeneratedCipherText), bytes(outGeneratedAuthTag)
def decrypt(self, data):
def decrypt(self, inGeneratedAuthTag, inGeneratedCipher):#plain text is the output and should be hello world
"""
Add more data to the decryption stream
"""
aad = bytes()
data = t2b(data)
inGeneratedCipher = t2b(inGeneratedCipher) #Should be the chipher from encrypt
if self._mode is None:
self._mode = _DECRYPTION
aad = self._aad
elif self._mode == _ENCRYPTION:
raise WolfCryptError("Class instance already in use for decryption")
self._buf = _ffi.new("byte[%d]" % (len(data)))
ret = _lib.wc_ChaCha20Poly1305_Decrypt(self._key, self_IV, aad, len(aad),
generatedCipherText, len(generatedCipherText),
authTag, generatedPlainText)
outPlainText= _ffi.new("byte[%d]" % (len(inGeneratedCipher)))#unsure what to put here
ret = _lib.wc_ChaCha20Poly1305_Decrypt(self._key, self._IV, aad, len(self._aad),
inGeneratedCipher, len(inGeneratedCipher),
inGeneratedAuthTag, outPlainText)
if ret < 0:
raise WolfCryptError("Decryption error (%d)" % ret)
return bytes(self._buf)
return bytes(outPlainText) # prettysure outplain text is the output
def checkTag(self, authTag):
"""
@ -530,6 +536,7 @@ if _lib.CHACHA20_POLY1305_ENABLED:
if authTag is None:
raise WolfCryptError("authTag parameter required")
authTag = t2b(authTag)
self._native_object = _ffi.new(self._native_type)
ret = _lib.wc_ChaCha20Poly1305_Final(self._native_type, authTag)
if ret < 0:
raise WolfCryptError("Decryption error (%d)" % ret)