Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement openSSL based AES 256 CCM #326

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,27 @@
"ignoreFailures": true
}
]
},

{
"name": "CHIP openSSL Tests",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/x86_64-unknown-linux-gnu/src/crypto/tests/TestOpenSSLCrypto",
Copy link
Contributor

@rwalker-apple rwalker-apple Apr 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is build/x86_64-unknown-linux-gnu working for you?

reason I ask is that tasks.json has been changed to build into build/default

"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"preLaunchTask": "CHIP crypto Tests",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}
4 changes: 2 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1869,8 +1869,6 @@ src/Makefile
src/include/Makefile
src/ble/Makefile
src/ble/tests/Makefile
src/crypto/Makefile
src/crypto/tests/Makefile
src/lwip/Makefile
src/lwip/tests/Makefile
src/system/Makefile
Expand All @@ -1884,6 +1882,8 @@ src/lib/core/tests/Makefile
src/lib/support/Makefile
src/lib/support/tests/Makefile
src/platform/Makefile
src/crypto/Makefile
src/crypto/tests/Makefile
tests/Makefile
])

Expand Down
1 change: 0 additions & 1 deletion src/crypto/CHIPCryptoPAL.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ CHIP_ERROR CHIP_aes_ccm_256_encrypt(const unsigned char * plaintext, size_t plai
* @param plaintext Buffer to write plaintext into
* @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
**/

CHIP_ERROR CHIP_aes_ccm_256_decrypt(const unsigned char * ciphertext, size_t ciphertext_length, const unsigned char * aad,
size_t aad_length, const unsigned char * tag, size_t tag_length, const unsigned char * key,
const unsigned char * iv, size_t iv_length, unsigned char * plaintext);
Expand Down
39 changes: 0 additions & 39 deletions src/crypto/CHIPCryptoPALOpenSSL.c

This file was deleted.

170 changes: 170 additions & 0 deletions src/crypto/CHIPCryptoPALOpenSSL.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
/*
*
* Copyright (c) 2020 Project CHIP Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* @file
* openSSL based implementation of CHIP crypto primitives
*/

#include "CHIPCryptoPAL.h"

#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <support/CodeUtils.h>
#include <string.h>

#define kKeyLengthInBits 256

bool _isValidTagLength(size_t tag_length)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this be static (i.e. not exported?)

{
if (tag_length == 8 || tag_length == 12 || tag_length == 16)
{
return true;
}
return false;
}

CHIP_ERROR CHIP_aes_ccm_256_encrypt(const unsigned char * plaintext, size_t plaintext_length, const unsigned char * aad,
size_t aad_length, const unsigned char * key, const unsigned char * iv, size_t iv_length,
unsigned char * ciphertext, unsigned char * tag, size_t tag_length)
{
EVP_CIPHER_CTX * context = NULL;
int bytesWritten = 0;
size_t ciphertext_length = 0;
CHIP_ERROR error = CHIP_NO_ERROR;
int result = 1;

VerifyOrExit((plaintext != NULL && plaintext_length > 0), error = CHIP_ERROR_INVALID_ARGUMENT);

VerifyOrExit(key != NULL, error = CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrExit(iv != NULL && iv_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrExit(_isValidTagLength(tag_length), error = CHIP_ERROR_INVALID_ARGUMENT);

context = EVP_CIPHER_CTX_new();
VerifyOrExit(context != NULL, error = CHIP_ERROR_INTERNAL);

// Pass in cipher
result = EVP_EncryptInit_ex(context, EVP_aes_256_ccm(), NULL, NULL, NULL);
VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);

// Pass in IV length
result = EVP_CIPHER_CTX_ctrl(context, EVP_CTRL_AEAD_SET_IVLEN, iv_length, NULL);
VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);

// Pass in tag length
result = EVP_CIPHER_CTX_ctrl(context, EVP_CTRL_CCM_SET_TAG, tag_length, NULL);
VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);

// Pass in key + iv
result = EVP_EncryptInit_ex(context, NULL, NULL, key, iv);
VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);

// Pass in plain text length
result = EVP_EncryptUpdate(context, NULL, &bytesWritten, NULL, plaintext_length);
VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);

// Pass in AAD
if (aad_length > 0)
{
result = EVP_EncryptUpdate(context, NULL, &bytesWritten, aad, aad_length);
VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
}

// Encrypt
result = EVP_EncryptUpdate(context, ciphertext, &bytesWritten, plaintext, plaintext_length);
VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
ciphertext_length = bytesWritten;

// Finalize encryption
result = EVP_EncryptFinal_ex(context, ciphertext + ciphertext_length, &bytesWritten);
VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
ciphertext_length += bytesWritten;

// Get tag
EVP_CIPHER_CTX_ctrl(context, EVP_CTRL_CCM_GET_TAG, tag_length, tag);

exit:
if (context != NULL)
{
EVP_CIPHER_CTX_free(context);
context = NULL;
}

return error;
}

CHIP_ERROR CHIP_aes_ccm_256_decrypt(const unsigned char * ciphertext, size_t ciphertext_length, const unsigned char * aad,
size_t aad_length, const unsigned char * tag, size_t tag_length, const unsigned char * key,
const unsigned char * iv, size_t iv_length, unsigned char * plaintext)
{
EVP_CIPHER_CTX * context = NULL;
CHIP_ERROR error = CHIP_NO_ERROR;
int bytesOutput = 0;
int result = 1;

VerifyOrExit(ciphertext != NULL, error = CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrExit(ciphertext_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrExit(tag != NULL, error = CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrExit(tag_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrExit(key != NULL, error = CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrExit(iv != NULL, error = CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrExit(iv_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);

context = EVP_CIPHER_CTX_new();
VerifyOrExit(context != NULL, error = CHIP_ERROR_INTERNAL);

// Pass in cipher
result = EVP_DecryptInit_ex(context, EVP_aes_256_ccm(), NULL, NULL, NULL);
VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);

// Pass in IV length
result = EVP_CIPHER_CTX_ctrl(context, EVP_CTRL_AEAD_SET_IVLEN, iv_length, NULL);
VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);

// Pass in expected tag
result = EVP_CIPHER_CTX_ctrl(context, EVP_CTRL_AEAD_SET_TAG, tag_length, (void *) tag);
VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);

// Pass in key + iv
result = EVP_DecryptInit_ex(context, NULL, NULL, key, iv);
VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);

// Pass in cipher text length
result = EVP_DecryptUpdate(context, NULL, &bytesOutput, NULL, ciphertext_length);
VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);

// Pass in aad
if (aad_length > 0)
{
result = EVP_DecryptUpdate(context, NULL, &bytesOutput, aad, aad_length);
VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
}

// Pass in ciphertext
result = EVP_DecryptUpdate(context, plaintext, &bytesOutput, ciphertext, ciphertext_length);
VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);

exit:
if (context != NULL)
{
EVP_CIPHER_CTX_free(context);
context = NULL;
}

return error;
}
20 changes: 19 additions & 1 deletion src/crypto/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ include $(abs_top_nlbuild_autotools_dir)/automake/pre.am

SUBDIRS = tests

lib_LIBRARIES = libChipCrypto.a
lib_LIBRARIES = libChipCrypto.a libChipCryptoOpenSSL.a

libChipCrypto_adir = $(includedir)/crypto

Expand All @@ -45,6 +45,24 @@ dist_libChipCrypto_a_HEADERS = \
CHIPCryptoPAL.h \
$(NULL)

# Build openSSL based crypto as a separate library
libChipCryptoOpenSSL_adir = $(includedir)/crypto

libChipCryptoOpenSSL_a_CPPFLAGS = \
-I$(top_srcdir)/src \
-I$(top_srcdir)/src/lib \
-I$(top_srcdir)/src/system \
-I$(top_srcdir)/src/include/ \
$(NULL)

libChipCryptoOpenSSL_a_SOURCES = \
CHIPCryptoPALOpenSSL.cpp \
$(NULL)

dist_libChipCrypto_a_HEADERS = \
CHIPCryptoPAL.h \
$(NULL)

$(RECURSIVE_TARGETS): $(lib_LIBRARIES)

include $(abs_top_nlbuild_autotools_dir)/automake/post.am
Loading