Skip to content

Commit

Permalink
Create CRT API for accessing symmetric cipher state
Browse files Browse the repository at this point in the history
Create CRT API for creating dynamically sized byte buf
  • Loading branch information
sbiscigl committed May 17, 2024
1 parent cac7ca5 commit 4594db9
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 3 deletions.
1 change: 1 addition & 0 deletions include/aws/crt/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ namespace Aws
AWS_CRT_CPP_API ByteBuf ByteBufFromEmptyArray(const uint8_t *array, size_t len) noexcept;
AWS_CRT_CPP_API ByteBuf ByteBufFromArray(const uint8_t *array, size_t capacity) noexcept;
AWS_CRT_CPP_API ByteBuf ByteBufNewCopy(Allocator *alloc, const uint8_t *array, size_t len);
AWS_CRT_CPP_API ByteBuf ByteBufInit(Allocator *alloc, size_t len);
AWS_CRT_CPP_API void ByteBufDelete(ByteBuf &);

AWS_CRT_CPP_API ByteCursor ByteCursorFromCString(const char *str) noexcept;
Expand Down
14 changes: 14 additions & 0 deletions include/aws/crt/crypto/SymmetricCipher.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#include <aws/cal/symmetric_cipher.h>
#include <aws/crt/Exports.h>
#include <aws/crt/Types.h>

Expand All @@ -17,6 +18,13 @@ namespace Aws
static const size_t AES_256_CIPHER_BLOCK_SIZE = 16u;
static const size_t AES_256_KEY_SIZE_BYTES = 32u;

enum class SymmetricCipherState
{
Ready = AWS_SYMMETRIC_CIPHER_READY,
Finalized = AWS_SYMMETRIC_CIPHER_FINALIZED,
Error = AWS_SYMMETRIC_CIPHER_ERROR,
};

class AWS_CRT_CPP_API SymmetricCipher final
{
public:
Expand Down Expand Up @@ -71,6 +79,12 @@ namespace Aws
*/
operator bool() const noexcept;

/**
* Returns current state of the cipher instance. ready to be used, finalized, or in a error state.
* If the cipher is in a finalized or error state it may not be used anymore
**/
SymmetricCipherState GetState() const noexcept;

/**
* Returns the value of the last aws error encountered by operations on this instance.
*/
Expand Down
7 changes: 7 additions & 0 deletions source/Types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ namespace Aws
return retVal;
}

ByteBuf ByteBufInit(Allocator *alloc, size_t len)
{
ByteBuf buff;
aws_byte_buf_init(&buff, alloc, len);
return buff;
}

void ByteBufDelete(ByteBuf &buf) { aws_byte_buf_clean_up(&buf); }

ByteCursor ByteCursorFromCString(const char *str) noexcept { return aws_byte_cursor_from_c_str(str); }
Expand Down
11 changes: 9 additions & 2 deletions source/crypto/SymmetricCipher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
#include <aws/crt/Api.h>
#include <aws/crt/crypto/SymmetricCipher.h>

#include <aws/cal/symmetric_cipher.h>

namespace Aws
{
namespace Crt
Expand All @@ -27,6 +25,15 @@ namespace Aws
return m_cipher != nullptr ? aws_symmetric_cipher_is_good(m_cipher.get()) : false;
}

SymmetricCipherState SymmetricCipher::GetState() const noexcept
{
if (m_cipher == nullptr)
{
return SymmetricCipherState::Error;
}
return static_cast<SymmetricCipherState>(aws_symmetric_cipher_get_state(m_cipher.get()));
}

bool SymmetricCipher::Encrypt(const ByteCursor &toEncrypt, ByteBuf &out) noexcept
{
if (!*this)
Expand Down
27 changes: 27 additions & 0 deletions tests/SymmetricCipherTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,30 @@ static int s_TestAES_256_CBC_Generated_Materials_ResourceSafety(struct aws_alloc
auto cbcCipher = Aws::Crt::Crypto::SymmetricCipher::CreateAES_256_CBC_Cipher();

ASSERT_TRUE(cbcCipher);
ASSERT_TRUE(cbcCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Ready);

auto input = aws_byte_cursor_from_c_str("abc");

uint8_t output[Aws::Crt::Crypto::AES_256_CIPHER_BLOCK_SIZE * 2] = {0};
auto outputBuf = Aws::Crt::ByteBufFromEmptyArray(output, sizeof(output));

ASSERT_TRUE(cbcCipher.Encrypt(input, outputBuf));
ASSERT_TRUE(cbcCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Ready);
ASSERT_TRUE(cbcCipher.FinalizeEncryption(outputBuf));
ASSERT_TRUE(cbcCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Finalized);

ASSERT_FALSE(cbcCipher);

ASSERT_TRUE(cbcCipher.Reset());
ASSERT_TRUE(cbcCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Ready);

auto decryptInput = Aws::Crt::ByteCursorFromByteBuf(outputBuf);
outputBuf.len = 0;

ASSERT_TRUE(cbcCipher.Decrypt(decryptInput, outputBuf));
ASSERT_TRUE(cbcCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Ready);
ASSERT_TRUE(cbcCipher.FinalizeDecryption(outputBuf));
ASSERT_TRUE(cbcCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Finalized);

ASSERT_BIN_ARRAYS_EQUALS(input.ptr, input.len, outputBuf.buffer, outputBuf.len);

Expand All @@ -48,6 +54,7 @@ static int s_TestAES_256_CBC_Generated_Materials_ResourceSafety(struct aws_alloc
uint8_t key[Aws::Crt::Crypto::AES_256_KEY_SIZE_BYTES] = {0xDD};
auto keyCur = Aws::Crt::ByteCursorFromArray(key, sizeof(key));
cbcCipher = Aws::Crt::Crypto::SymmetricCipher::CreateAES_256_CBC_Cipher(keyCur);
ASSERT_TRUE(cbcCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Ready);
ASSERT_TRUE(cbcCipher);
ASSERT_BIN_ARRAYS_EQUALS(keyCur.ptr, keyCur.len, cbcCipher.GetKey().ptr, cbcCipher.GetKey().len);
ASSERT_UINT_EQUALS(Aws::Crt::Crypto::AES_256_CIPHER_BLOCK_SIZE, cbcCipher.GetIV().len);
Expand All @@ -64,24 +71,30 @@ static int s_TestAES_256_CTR_Generated_Materials_ResourceSafety(struct aws_alloc
Aws::Crt::ApiHandle apiHandle(allocator);
auto ctrCipher = Aws::Crt::Crypto::SymmetricCipher::CreateAES_256_CTR_Cipher();
ASSERT_TRUE(ctrCipher);
ASSERT_TRUE(ctrCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Ready);

auto input = aws_byte_cursor_from_c_str("abc");

uint8_t output[Aws::Crt::Crypto::AES_256_CIPHER_BLOCK_SIZE * 2] = {0};
auto outputBuf = Aws::Crt::ByteBufFromEmptyArray(output, sizeof(output));

ASSERT_TRUE(ctrCipher.Encrypt(input, outputBuf));
ASSERT_TRUE(ctrCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Ready);
ASSERT_TRUE(ctrCipher.FinalizeEncryption(outputBuf));
ASSERT_TRUE(ctrCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Finalized);

ASSERT_FALSE(ctrCipher);

ASSERT_TRUE(ctrCipher.Reset());
ASSERT_TRUE(ctrCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Ready);

auto decryptInput = Aws::Crt::ByteCursorFromByteBuf(outputBuf);
outputBuf.len = 0;

ASSERT_TRUE(ctrCipher.Decrypt(decryptInput, outputBuf));
ASSERT_TRUE(ctrCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Ready);
ASSERT_TRUE(ctrCipher.FinalizeDecryption(outputBuf));
ASSERT_TRUE(ctrCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Finalized);

ASSERT_BIN_ARRAYS_EQUALS(input.ptr, input.len, outputBuf.buffer, outputBuf.len);

Expand All @@ -97,6 +110,7 @@ static int s_TestAES_256_CTR_Generated_Materials_ResourceSafety(struct aws_alloc
auto keyCur = Aws::Crt::ByteCursorFromArray(key, sizeof(key));
ctrCipher = Aws::Crt::Crypto::SymmetricCipher::CreateAES_256_CTR_Cipher(keyCur);
ASSERT_TRUE(ctrCipher);
ASSERT_TRUE(ctrCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Ready);
ASSERT_BIN_ARRAYS_EQUALS(keyCur.ptr, keyCur.len, ctrCipher.GetKey().ptr, ctrCipher.GetKey().len);
ASSERT_UINT_EQUALS(Aws::Crt::Crypto::AES_256_CIPHER_BLOCK_SIZE, ctrCipher.GetIV().len);
}
Expand All @@ -112,24 +126,30 @@ static int s_TestAES_256_GCM_Generated_Materials_ResourceSafety(struct aws_alloc
Aws::Crt::ApiHandle apiHandle(allocator);
auto gcmCipher = Aws::Crt::Crypto::SymmetricCipher::CreateAES_256_GCM_Cipher();
ASSERT_TRUE(gcmCipher);
ASSERT_TRUE(gcmCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Ready);

auto input = aws_byte_cursor_from_c_str("abc");

uint8_t output[Aws::Crt::Crypto::AES_256_CIPHER_BLOCK_SIZE * 2] = {0};
auto outputBuf = Aws::Crt::ByteBufFromEmptyArray(output, sizeof(output));

ASSERT_TRUE(gcmCipher.Encrypt(input, outputBuf));
ASSERT_TRUE(gcmCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Ready);
ASSERT_TRUE(gcmCipher.FinalizeEncryption(outputBuf));
ASSERT_TRUE(gcmCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Finalized);

ASSERT_FALSE(gcmCipher);

ASSERT_TRUE(gcmCipher.Reset());
ASSERT_TRUE(gcmCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Ready);

auto decryptInput = Aws::Crt::ByteCursorFromByteBuf(outputBuf);
outputBuf.len = 0;

ASSERT_TRUE(gcmCipher.Decrypt(decryptInput, outputBuf));
ASSERT_TRUE(gcmCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Ready);
ASSERT_TRUE(gcmCipher.FinalizeDecryption(outputBuf));
ASSERT_TRUE(gcmCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Finalized);

ASSERT_BIN_ARRAYS_EQUALS(input.ptr, input.len, outputBuf.buffer, outputBuf.len);

Expand All @@ -146,6 +166,7 @@ static int s_TestAES_256_GCM_Generated_Materials_ResourceSafety(struct aws_alloc
auto keyCur = Aws::Crt::ByteCursorFromArray(key, sizeof(key));
gcmCipher = Aws::Crt::Crypto::SymmetricCipher::CreateAES_256_GCM_Cipher(keyCur);
ASSERT_TRUE(gcmCipher);
ASSERT_TRUE(gcmCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Ready);
ASSERT_BIN_ARRAYS_EQUALS(keyCur.ptr, keyCur.len, gcmCipher.GetKey().ptr, gcmCipher.GetKey().len);
ASSERT_UINT_EQUALS(Aws::Crt::Crypto::AES_256_CIPHER_BLOCK_SIZE - 4, gcmCipher.GetIV().len);
}
Expand All @@ -161,26 +182,32 @@ static int s_TestAES_256_Keywrap_Generated_Materials_ResourceSafety(struct aws_a
Aws::Crt::ApiHandle apiHandle(allocator);
auto keywrapCipher = Aws::Crt::Crypto::SymmetricCipher::CreateAES_256_KeyWrap_Cipher();
ASSERT_TRUE(keywrapCipher);
ASSERT_TRUE(keywrapCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Ready);

auto input = aws_byte_cursor_from_c_str("abcdefghijklmnopqrstuvwxyz123456");

uint8_t output[Aws::Crt::Crypto::AES_256_CIPHER_BLOCK_SIZE * 3] = {0};
auto outputBuf = Aws::Crt::ByteBufFromEmptyArray(output, sizeof(output));

ASSERT_TRUE(keywrapCipher.Encrypt(input, outputBuf));
ASSERT_TRUE(keywrapCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Ready);
ASSERT_TRUE(keywrapCipher.FinalizeEncryption(outputBuf));
ASSERT_TRUE(keywrapCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Finalized);

ASSERT_FALSE(keywrapCipher);

ASSERT_TRUE(keywrapCipher.Reset());
ASSERT_TRUE(keywrapCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Ready);

uint8_t decryptOutput[Aws::Crt::Crypto::AES_256_CIPHER_BLOCK_SIZE * 3] = {0};
auto decryptOutputBuf = Aws::Crt::ByteBufFromEmptyArray(decryptOutput, sizeof(decryptOutput));

auto decryptInput = Aws::Crt::ByteCursorFromByteBuf(outputBuf);

ASSERT_TRUE(keywrapCipher.Decrypt(decryptInput, decryptOutputBuf));
ASSERT_TRUE(keywrapCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Ready);
ASSERT_TRUE(keywrapCipher.FinalizeDecryption(decryptOutputBuf));
ASSERT_TRUE(keywrapCipher.GetState() == Aws::Crt::Crypto::SymmetricCipherState::Finalized);

ASSERT_BIN_ARRAYS_EQUALS(input.ptr, input.len, decryptOutputBuf.buffer, decryptOutputBuf.len);

Expand Down
14 changes: 14 additions & 0 deletions tests/TypesTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,17 @@ static int s_byte_cursor_array_list_to_vector(struct aws_allocator *allocator, v
}

AWS_TEST_CASE(TestByteCursorArrayListToVector, s_byte_cursor_array_list_to_vector)

static int s_byte_buff_init_delete(struct aws_allocator *allocator, void *ctx)
{
const auto targetLength = 8;
auto byteBuff = ByteBufInit(allocator, targetLength);
ASSERT_UINT_EQUALS(targetLength, byteBuff.len);
ASSERT_TRUE(byteBuff.buffer != nullptr);
ByteBufDelete(byteBuff);
ASSERT_UINT_EQUALS(targetLength, 0);
ASSERT_TRUE(byteBuff.buffer == nullptr);
return 0;
}

AWS_TEST_CASE(TestByteBufInitDelete, s_byte_buff_init_delete)

0 comments on commit 4594db9

Please sign in to comment.