Skip to content

Commit

Permalink
Add procedures for AES encryption/decryption
Browse files Browse the repository at this point in the history
  • Loading branch information
chpock committed Jul 8, 2024
1 parent 75b7ca7 commit 073d963
Show file tree
Hide file tree
Showing 11 changed files with 1,899 additions and 21 deletions.
3 changes: 3 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
2024-07-08 Konstantin Kushnir <[email protected]>
* Add procedures for AES encryption/decryption

2024-07-07 Konstantin Kushnir <[email protected]>
* Add basic cryptographic functions
* Add 1 test case for threads
Expand Down
48 changes: 48 additions & 0 deletions generic/crypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

#include "cookfs.h"
#include "crypt.h"

// for getpid()
#include <unistd.h>
Expand Down Expand Up @@ -37,6 +38,53 @@ typedef struct {
CSha256 outer;
} HMAC_CTX;

#if COOKFS_PAGEOBJ_BLOCK_SIZE != AES_BLOCK_SIZE
#error Condition COOKFS_PAGEOBJ_BLOCK_SIZE == AES_BLOCK_SIZE is not true. Is is unsupported. Buffer owerflow errors are expected in Cookfs_Aes* functions.
#endif

void Cookfs_AesEncrypt(Cookfs_PageObj pg, unsigned char *key) {

CookfsLog2(printf("enter..."));

UInt32 ivAes[AES_NUM_IVMRK_WORDS];

Cookfs_PageObjAddPadding(pg);

AesCbc_Init(ivAes, Cookfs_PageObjGetIV(pg));
// ivAes is a pointer to 32-bit integers. But IV size is defined in 8-bit
// AES_BLOCK_SIZE blocks. So here we use an offset of 4 (32 / 8).
Aes_SetKey_Enc(ivAes + 4, key, COOKFS_ENCRYPT_KEY_SIZE);

CookfsLog2(printf("run AesCbc_Encode() ..."));
AesCbc_Encode(ivAes, pg, Cookfs_PageObjSize(pg) / AES_BLOCK_SIZE);

CookfsLog2(printf("ok"));
return;

}

int Cookfs_AesDecrypt(Cookfs_PageObj pg, unsigned char *key) {

CookfsLog2(printf("enter..."));

UInt32 ivAes[AES_NUM_IVMRK_WORDS];

AesCbc_Init(ivAes, Cookfs_PageObjGetIV(pg));
// ivAes is a pointer to 32-bit integers. But IV size is defined in 8-bit
// AES_BLOCK_SIZE blocks. So here we use an offset of 4 (32 / 8).
Aes_SetKey_Dec(ivAes + 4, key, COOKFS_ENCRYPT_KEY_SIZE);

CookfsLog2(printf("run AesCbc_Decode() ..."));
AesCbc_Decode(ivAes, pg, Cookfs_PageObjSize(pg) / AES_BLOCK_SIZE);

CookfsLog2(printf("unpad data ..."));
int rc = Cookfs_PageObjRemovePadding(pg);

CookfsLog2(printf("return %s", (rc == TCL_OK ? "TCL_OK" : "TCL_ERROR")));
return rc;

}

static void Cookfs_HmacInit(HMAC_CTX *ctx, unsigned char *key,
Tcl_Size keySize)
{
Expand Down
10 changes: 10 additions & 0 deletions generic/crypt.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,21 @@
#ifndef COOKFS_CRYPT_H
#define COOKFS_CRYPT_H 1

#include "pageObj.h"

// Size of encryption key in bytes. We use AES265, so it is defined
// as 32 bytes.

#define COOKFS_ENCRYPT_KEY_SIZE 32

void Cookfs_CryptInit(void);

void Cookfs_RandomGenerate(Tcl_Interp *interp, unsigned char *buf, Tcl_Size size);
void Cookfs_Pbkdf2Hmac(unsigned char *secret, Tcl_Size secretSize,
unsigned char *salt, Tcl_Size saltSize, unsigned int iterations,
unsigned int dklen, unsigned char *output);

void Cookfs_AesEncrypt(Cookfs_PageObj pg, unsigned char *key);
int Cookfs_AesDecrypt(Cookfs_PageObj pg, unsigned char *key);

#endif /* COOKFS_CRYPT_H */
106 changes: 106 additions & 0 deletions generic/cryptCmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,102 @@

#include "cookfs.h"
#include "crypt.h"
#include "cryptCmd.h"

static int CookfsAesEncryptObjectCmd(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
UNUSED(clientData);

if ((objc != 3 && objc != 5) || (objc == 5 &&
strcmp(Tcl_GetString(objv[1]), "-iv") != 0))
{
Tcl_WrongNumArgs(interp, 1, objv, "?-iv iv? data key");
return TCL_ERROR;
}

Tcl_Size keyLen;
unsigned char *keyStr = Tcl_GetByteArrayFromObj(objv[objc - 1], &keyLen);

if (keyLen != COOKFS_ENCRYPT_KEY_SIZE) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf("the key size must be exactly"
" %d bytes, but a key of %" TCL_SIZE_MODIFIER "d bytes"
" is specified", COOKFS_ENCRYPT_KEY_SIZE, keyLen));
return TCL_ERROR;
}

Tcl_Size ivLen;
unsigned char *ivStr;
if (objc == 5) {
ivStr = Tcl_GetByteArrayFromObj(objv[2], &ivLen);
if (ivLen != COOKFS_PAGEOBJ_BLOCK_SIZE) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf("the IV size must be exactly"
" %d bytes, but an IV of %" TCL_SIZE_MODIFIER "d bytes"
" is specified", COOKFS_PAGEOBJ_BLOCK_SIZE, ivLen));
return TCL_ERROR;
}
} else {
ivStr = NULL;
}

Cookfs_PageObj pg = Cookfs_PageObjNewFromByteArray(objv[objc - 2]);

if (ivStr != NULL) {
Cookfs_PageObjSetIV(pg, ivStr);
}

Cookfs_AesEncrypt(pg, keyStr);

Tcl_SetObjResult(interp, Cookfs_PageObjCopyAsByteArrayIV(pg));

Cookfs_PageObjBounceRefCount(pg);

return TCL_OK;

}

static int CookfsAesDecryptObjectCmd(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
UNUSED(clientData);

if (objc != 3) {
Tcl_WrongNumArgs(interp, 1, objv, "data key");
return TCL_ERROR;
}

Tcl_Size keyLen;
unsigned char *keyStr = Tcl_GetByteArrayFromObj(objv[2], &keyLen);

if (keyLen != COOKFS_ENCRYPT_KEY_SIZE) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf("the key size must be exactly"
" %d bytes, but a key of %" TCL_SIZE_MODIFIER "d bytes"
" is specified", COOKFS_ENCRYPT_KEY_SIZE, keyLen));
return TCL_ERROR;
}

Cookfs_PageObj pg = Cookfs_PageObjNewFromByteArrayIV(objv[1]);

if (pg == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("unencrypted data was"
" specified", -1));
return TCL_ERROR;
}

int rc = Cookfs_AesDecrypt(pg, keyStr);

if (rc != TCL_OK) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("failed to decrypt"
" the specified data", -1));
} else {
Tcl_SetObjResult(interp, Cookfs_PageObjCopyAsByteArray(pg));
}

Cookfs_PageObjBounceRefCount(pg);

return rc;

}

static int CookfsRandomGenerateObjectCmd(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Expand Down Expand Up @@ -105,10 +201,20 @@ int Cookfs_InitCryptCmd(Tcl_Interp *interp) {
Tcl_CreateObjCommand(interp, "::cookfs::c::crypt::pbkdf2_hmac",
CookfsPbkdf2HmacObjectCmd, (ClientData) NULL, NULL);

Tcl_CreateObjCommand(interp, "::cookfs::c::crypt::aes_encrypt",
CookfsAesEncryptObjectCmd, (ClientData) NULL, NULL);

Tcl_CreateObjCommand(interp, "::cookfs::c::crypt::aes_decrypt",
CookfsAesDecryptObjectCmd, (ClientData) NULL, NULL);

Tcl_CreateAlias(interp, "::cookfs::crypt::rng", interp,
"::cookfs::c::crypt::rng", 0, NULL);
Tcl_CreateAlias(interp, "::cookfs::crypt::pbkdf2_hmac", interp,
"::cookfs::c::crypt::pbkdf2_hmac", 0, NULL);
Tcl_CreateAlias(interp, "::cookfs::crypt::aes_encrypt", interp,
"::cookfs::c::crypt::aes_encrypt", 0, NULL);
Tcl_CreateAlias(interp, "::cookfs::crypt::aes_decrypt", interp,
"::cookfs::c::crypt::aes_decrypt", 0, NULL);

return TCL_OK;

Expand Down
Loading

0 comments on commit 073d963

Please sign in to comment.