Skip to content

Commit

Permalink
Merge pull request #9 from atsign-foundation/jeremy-rsa2048
Browse files Browse the repository at this point in the history
feat: RSA MVP
  • Loading branch information
JeremyTubongbanua authored Jul 10, 2023
2 parents 4375397 + 68ebe2f commit 3aeb9ad
Show file tree
Hide file tree
Showing 20 changed files with 1,091 additions and 33 deletions.
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[submodule "deps/mbedtls"]
path = deps/mbedtls
url = https://github.com/Mbed-TLS/mbedtls
url = https://github.com/Mbed-TLS/mbedtls.git
[submodule "deps/esp-idf"]
path = deps/esp-idf
url = https://github.com/espressif/esp-idf.git
Expand Down
2 changes: 1 addition & 1 deletion .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"configurations": [
{
"name": "default",
"configurationProvider": "ms-vscode.cmake-tools",
// "configurationProvider": "ms-vscode.cmake-tools",
"includePath": [
"${default}",
"${workspaceFolder}/include/**",
Expand Down
32 changes: 28 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,35 @@ if(NOT BUILD_ESP_IDF) # build for other platforms
NAME AES_CTR
COMMAND $<TARGET_FILE:test_aes_ctr>)

add_executable(test_main test/test_main.c)
target_link_libraries(test_main PRIVATE at_client)
add_executable(test_rsapublicpopulate test/test_rsapublicpopulate.c)
target_link_libraries(test_rsapublicpopulate PRIVATE at_client)
add_test(
NAME MAIN
COMMAND $<TARGET_FILE:test_main>)
NAME RSA_PUBLICPOPULATE
COMMAND $<TARGET_FILE:test_rsapublicpopulate>)

add_executable(test_rsaprivatepopulate test/test_rsaprivatepopulate.c)
target_link_libraries(test_rsaprivatepopulate PRIVATE at_client)
add_test(
NAME RSA_PRIVATEPOPULATE
COMMAND $<TARGET_FILE:test_rsaprivatepopulate>)

add_executable(test_rsasign test/test_rsasign.c)
target_link_libraries(test_rsasign PRIVATE at_client)
add_test(
NAME RSA_SIGN
COMMAND $<TARGET_FILE:test_rsasign>)

add_executable(test_rsaencrypt test/test_rsaencrypt.c)
target_link_libraries(test_rsaencrypt PRIVATE at_client)
add_test(
NAME RSA_ENCRYPT
COMMAND $<TARGET_FILE:test_rsaencrypt>)

add_executable(test_rsadecrypt test/test_rsadecrypt.c)
target_link_libraries(test_rsadecrypt PRIVATE at_client)
add_test(
NAME RSA_DECRYPT
COMMAND $<TARGET_FILE:test_rsadecrypt>)

# compiler flags
target_compile_options(at_client # https://vladiant.github.io/blog/2021/08/14/cpp-compiler-flags
Expand Down
5 changes: 3 additions & 2 deletions include/at_chops.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ extern "C"
{
#endif

#include "base64.h"
#include "aes_ctr.h"
#include "at_chops/base64.h"
#include "at_chops/aes_ctr.h"
#include "at_chops/rsa.h"

#ifdef __cplusplus
}
Expand Down
22 changes: 11 additions & 11 deletions include/at_chops/aes_ctr.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#pragma once

// #ifdef BUILD_MBEDTLS
// #ifdef __cplusplus
// extern "C"
// {
// #endif
#ifdef BUILD_MBEDTLS
#ifdef __cplusplus
extern "C"
{
#endif

#include <string.h>

Expand All @@ -23,7 +23,7 @@ typedef struct {
} AESResult;

/**
* @brief AES 256 CTR encrypt plaintext
* @brief AES CTR encrypt plaintext
*
* @param key_base64 the base64 encoded AES 256 key (e.g. "1DPU9OP3CYvamnVBMwGgL7fm8yB1klAap0Uc5Z9R79g=")
* @param plaintext the plain text to encryt, must be null terminated `\0`
Expand All @@ -32,15 +32,15 @@ typedef struct {
AESResult *atchops_aes_ctr_encrypt(const char *key_base64, const AESKeySize key_size, const unsigned char *plaintext);

/**
* @brief AES 256 CTR decrypt cipher text
* @brief AES CTR decrypt cipher text
*
* @param key_base64 the base64 encoded AES 256 key (e.g. "1DPU9OP3CYvamnVBMwGgL7fm8yB1klAap0Uc5Z9R79g=")
* @param ciphertext the base64 encoded cipher text, must be null terminated `\0`
* @return AESResult* the result of the decrytion
*/
AESResult *atchops_aes_ctr_decrypt(const char *key_base64, const AESKeySize key_size, const unsigned char *ciphertext);

// #ifdef __cplusplus
// }
// #endif
// #endif
#ifdef __cplusplus
}
#endif
#endif
2 changes: 2 additions & 0 deletions include/at_chops/base64.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ extern "C"

#include <stddef.h>

#define MAX_TEXT_LENGTH_FORBASE64_ENCODING_OPERATION 10000 // the max length of base64 encoded text (should be more than enough)

/**
* @brief Encodes a string to base64
*
Expand Down
13 changes: 13 additions & 0 deletions include/at_chops/byteutil.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

#ifdef __cplusplus
extern "C" {
#endif

void printx(unsigned char *data, size_t len);

void copy(unsigned char *dst, unsigned char *src, size_t len);

#ifdef __cplusplus
}
#endif
84 changes: 84 additions & 0 deletions include/at_chops/rsa.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#pragma once

#ifdef BUILD_MBEDTLS
#ifdef __cplusplus
extern "C"
{
#endif

#include <ctype.h>

typedef struct rsa_param {
size_t len;
unsigned char *value; // hex byte array of the number
} rsa_param;

typedef struct {
rsa_param n_param; // modulus
rsa_param e_param; // public exponent
} atchops_rsa2048_publickey;

typedef struct {
rsa_param n_param; // modulus
rsa_param e_param; // public exponent
rsa_param d_param; // private exponent
rsa_param p_param; // prime 1
rsa_param q_param; // prime 2
} atchops_rsa2048_privatekey;

typedef enum {
ATCHOPS_MD_NONE=0, /**< None. */
ATCHOPS_MD_MD5, /**< The MD5 message digest. */
ATCHOPS_MD_SHA1, /**< The SHA-1 message digest. */
ATCHOPS_MD_SHA224, /**< The SHA-224 message digest. */
ATCHOPS_MD_SHA256, /**< The SHA-256 message digest. */
ATCHOPS_MD_SHA384, /**< The SHA-384 message digest. */
ATCHOPS_MD_SHA512, /**< The SHA-512 message digest. */
ATCHOPS_MD_RIPEMD160,
} atchops_md_type;

/**
* @brief Populate a public key struct from a base64 string
*
* @param publickeybase64 a base64 string representing an RSA 2048 Public Key
* @param publickeybase64len the length of the base64 string
* @param publickeystruct the public key struct to populate
* @return int 0 on success
*/
int atchops_rsa_populate_publickey(const char *publickeybase64, const size_t publickeybase64len, atchops_rsa2048_publickey *publickeystruct);

/**
* @brief Populate a private key struct from a base64 string
*
* @param privatekeybase64 the base64 string representing an RSA 2048 Private Key
* @param privatekeybase64len the length of the base64 string
* @param privatekeystruct the private key struct to populate
* @return int 0 on success
*/
int atchops_rsa_populate_privatekey(const char *privatekeybase64, const size_t privatekeybase64len, atchops_rsa2048_privatekey *privatekeystruct);

/**
* @brief Sign a message with an RSA 2048 Private Key
*
* @param privatekeystruct the private key struct to use for signing
* @param mdtype the message digest type to use
* @param signature the signature to populate. Pass in a pointer to a pointer to an unsigned char array. The pointer will be reassigned to the newly allocated array.
* @param signaturelen the output length of the signature
* @param message the message to sign
* @param messagelen the length of the message
* @return int 0 on success
*/
int atchops_rsa_sign(atchops_rsa2048_privatekey privatekeystruct, atchops_md_type mdtype, unsigned char **signature, size_t *signaturelen, const unsigned char *message, const size_t messagelen);

// todo
// int atchops_rsa2048_verify(atchops_rsa2048_publickey *publickeystruct, const unsigned char *signature, const size_t signaturelen, );

// todo comments
int atchops_rsa_encrypt(atchops_rsa2048_publickey publickeystruct, const char *plaintext, const size_t plaintextlen, char **ciphertext, size_t *ciphertextolen);

// todo comments
int atchops_rsa_decrypt(atchops_rsa2048_privatekey privatekeystruct, const char *ciphertextbase64encoded, const size_t ciphertextbase64encodedlen, char **plaintext, size_t *plaintextolen);
#ifdef __cplusplus
}
#endif
#endif
4 changes: 4 additions & 0 deletions run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash
# python3 tool.py -p desktop -f mbedtls clean
python3 tool.py -p desktop -f mbedtls build
python3 tool.py -p desktop -f mbedtls test
16 changes: 13 additions & 3 deletions src/at_chops/aes_ctr.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ extern "C"
#define IV_AMOUNT_BYTES 16

#define MAX_BYTES_ALLOCATED_FOR_ENCRYPTION_OPERATION 5000
#define MAX_TEXT_LENGTH_FORBASE64_ENCODING_OPERATION 10000 // the max length of base64 encoded text (should be more than enough)

AESResult *atchops_aes_ctr_encrypt(const char *key_base64, const AESKeySize key_size, const unsigned char *plaintext )
{
Expand Down Expand Up @@ -65,6 +64,8 @@ AESResult *atchops_aes_ctr_encrypt(const char *key_base64, const AESKeySize key_
unsigned char *stream_block = malloc(sizeof(unsigned char) * IV_AMOUNT_BYTES);
unsigned char *aes_encrypted = malloc(sizeof(unsigned char) * MAX_BYTES_ALLOCATED_FOR_ENCRYPTION_OPERATION);

// maybe base 64 encode it before feeding to cipher

// run encrypt
result->status = mbedtls_aes_crypt_ctr(ctx, plaintext_paddedlen, iv_ctr, iv, stream_block, plaintext_padded, aes_encrypted);

Expand Down Expand Up @@ -141,13 +142,22 @@ AESResult *atchops_aes_ctr_decrypt(const char *key_base64, const AESKeySize key_

// find the value of the pad
unsigned char pad_val = *(aes_decrypted + aes_decryptedlen - 2);
// printf("pad_val: %02x\n", pad_val);
if(pad_val >= 0x00 && pad_val <= 0x0F || pad_val == 0x10) // https://www.ibm.com/docs/en/zos/2.4.0?topic=rules-pkcs-padding-method
{
// eliminate that amount of padding
aes_decryptedlen -= (pad_val+1);
*(aes_decrypted+aes_decryptedlen) = '\0';
}

}

// printf("aa");
// printf("aa\n");
// for(int i = 0; i < aes_decryptedlen + 10; i++)
// {
// printf("%02x ", *(aes_decrypted+i));
// }
// printf("aa\n");

unsigned char *aes_decrypted_unpadded = malloc(sizeof(unsigned char) * aes_decryptedlen);
for (int i = 0; i < aes_decryptedlen; i++)
{
Expand Down
31 changes: 31 additions & 0 deletions src/at_chops/byteutil.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

#ifdef __cplusplus
extern "C"
{
#endif

#include <stdio.h>
#include "byteutil.h"

void printx(unsigned char *data, size_t len)
{
// TODO check len here, error handle return an int
for (size_t i = 0; i < len; i++)
{
printf("%02x ", data[i]);
}
printf("\n");
}

void copy(unsigned char *dst, unsigned char *src, size_t len)
{
// TODO: check len here, error handle return an int
for (size_t i = 0; i < len; i++)
{
dst[i] = src[i];
}
}

#ifdef __cplusplus
}
#endif
Loading

0 comments on commit 3aeb9ad

Please sign in to comment.