From 4816fe21bf1af56daf209b4349124117fdb942b8 Mon Sep 17 00:00:00 2001 From: seantywork Date: Thu, 4 Dec 2025 13:19:15 +0900 Subject: [PATCH] kcrypt material --- crypt-asym/certs/ca.srl | 1 + crypt-sym/main.c | 7 +- crypt-sym/sym.c | 95 +++++++++++------------ crypt-sym/sym.h | 4 +- kcrypt/2025-1204.xyz.md | 168 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 221 insertions(+), 54 deletions(-) create mode 100644 crypt-asym/certs/ca.srl diff --git a/crypt-asym/certs/ca.srl b/crypt-asym/certs/ca.srl new file mode 100644 index 0000000..83e9d93 --- /dev/null +++ b/crypt-asym/certs/ca.srl @@ -0,0 +1 @@ +6F28BBFA410EDF550BDF3A7A50E5D6DD1D2F8C2F diff --git a/crypt-sym/main.c b/crypt-sym/main.c index 317077c..1b60cd6 100644 --- a/crypt-sym/main.c +++ b/crypt-sym/main.c @@ -51,6 +51,7 @@ int main(int argc, char** argv){ char* key_path = "./key.data"; char* iv_path = "./iv.data"; + char* ad = "vvvvvvvv"; char* enc_msg = "cryptoinc"; @@ -58,7 +59,7 @@ int main(int argc, char** argv){ char* enc_path = "./enc.bin"; - int result = sym_encrypt(key_path, iv_path, enc_len, enc_msg, enc_path); + int result = sym_encrypt(key_path, iv_path, enc_len, enc_msg, enc_path, ad); } else if (strcmp(argv[1], "decrypt") == 0){ @@ -66,10 +67,10 @@ int main(int argc, char** argv){ char* key_path = "./key.data"; char* iv_path = "./iv.data"; char* enc_path = "./enc.bin"; - + char* ad = "vvvvvvvv"; char dec_msg[MAX_OUT] = {0}; - int result = sym_decrypt(key_path, iv_path, enc_path, dec_msg); + int result = sym_decrypt(key_path, iv_path, enc_path, dec_msg, ad); printf("%s\n", dec_msg); diff --git a/crypt-sym/sym.c b/crypt-sym/sym.c index f92ec92..f1f1a08 100644 --- a/crypt-sym/sym.c +++ b/crypt-sym/sym.c @@ -56,7 +56,7 @@ int sym_keygen(char* key_path, char* iv_path){ } -int sym_encrypt(char* key_path, char* iv_path, int enc_len, char* enc_msg, char* enc_path){ +int sym_encrypt(char* key_path, char* iv_path, int enc_len, char* enc_msg, char* enc_path, char* ad){ FILE* fp; @@ -64,7 +64,7 @@ int sym_encrypt(char* key_path, char* iv_path, int enc_len, char* enc_msg, char* int outlen, rv = 0; unsigned char outbuf[MAX_OUT] = {0}; - + int adlen = strlen(ad); #if CBC @@ -133,6 +133,26 @@ int sym_encrypt(char* key_path, char* iv_path, int enc_len, char* enc_msg, char* cbc_auth = hex2char(&outlen, (unsigned char*)cbc_auth_hex); + result = HMAC(EVP_sha256(), cbc_auth, KEYLEN, enc_msg, enc_len, result, &resultlen); + + if(result == NULL){ + + printf("hmac failed\n"); + } else { + + printf("hmac success\n"); + } + + unsigned char* auth_result_hex = char2hex(resultlen, result); + + fp = fopen("./auth.data", "w"); + + fputs(auth_result_hex, fp); + + fclose(fp); + + resultlen = 0; + ctx = EVP_CIPHER_CTX_new(); //EVP_CIPHER_CTX_set_padding(ctx, 0); @@ -159,24 +179,6 @@ int sym_encrypt(char* key_path, char* iv_path, int enc_len, char* enc_msg, char* fclose(fp); - result = HMAC(EVP_sha256(), cbc_auth, KEYLEN, outbuf, outlen, result, &resultlen); - - if(result == NULL){ - - printf("hmac failed\n"); - } else { - - printf("hmac success\n"); - } - - unsigned char* auth_result_hex = char2hex(resultlen, result); - - fp = fopen("./auth.data", "w"); - - fputs(auth_result_hex, fp); - - fclose(fp); - free(inbuf); EVP_CIPHER_CTX_free(ctx); @@ -198,8 +200,6 @@ int sym_encrypt(char* key_path, char* iv_path, int enc_len, char* enc_msg, char* unsigned char* gcm_iv; - unsigned char gcm_aad[8] = {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,}; - fp = fopen(key_path, "r"); @@ -228,7 +228,7 @@ int sym_encrypt(char* key_path, char* iv_path, int enc_len, char* enc_msg, char* EVP_EncryptInit(ctx, NULL, gcm_key, gcm_iv); - // EVP_EncryptUpdate(ctx, NULL, &outlen, gcm_aad, 8); + EVP_EncryptUpdate(ctx, NULL, &outlen, ad, adlen); EVP_EncryptUpdate(ctx, outbuf, &outlen, enc_msg, enc_len); @@ -271,7 +271,7 @@ int sym_encrypt(char* key_path, char* iv_path, int enc_len, char* enc_msg, char* -int sym_decrypt(char* key_path, char* iv_path, char* enc_path, char* dec_msg){ +int sym_decrypt(char* key_path, char* iv_path, char* enc_path, char* dec_msg, char* ad){ FILE* fp; @@ -281,6 +281,7 @@ int sym_decrypt(char* key_path, char* iv_path, char* enc_path, char* dec_msg){ int outlen, tmplen, rv; int bin_outlen = 0; + int adlen = strlen(ad); char inbuf[MAX_OUT] = {0}; @@ -348,27 +349,6 @@ int sym_decrypt(char* key_path, char* iv_path, char* enc_path, char* dec_msg){ unsigned char* inbuf_bin = hex2char(&bin_outlen, (unsigned char*)inbuf); - result = HMAC(EVP_sha256(), cbc_auth, KEYLEN, inbuf_bin, bin_outlen, result, &resultlen); - - if(result == NULL){ - - printf("hmac failed\n"); - - } else { - - printf("hmac success\n"); - - } - - if(memcmp(result, cbc_auth_val, 32) == 0){ - - printf("authenticated\n"); - } else { - printf("authentication failed\n"); - } - - - ctx = EVP_CIPHER_CTX_new(); //EVP_CIPHER_CTX_set_padding(ctx, 0); @@ -391,6 +371,26 @@ int sym_decrypt(char* key_path, char* iv_path, char* enc_path, char* dec_msg){ strcpy(dec_msg, outbuf); + result = HMAC(EVP_sha256(), cbc_auth, KEYLEN, dec_msg, plaintext_len, result, &resultlen); + + if(result == NULL){ + + printf("hmac failed\n"); + + } else { + + printf("hmac success\n"); + + } + + if(memcmp(result, cbc_auth_val, 32) == 0){ + + printf("authenticated\n"); + } else { + printf("authentication failed\n"); + } + + printf("decrypt rv: %d\n", rv); EVP_CIPHER_CTX_free(ctx); @@ -416,9 +416,6 @@ int sym_decrypt(char* key_path, char* iv_path, char* enc_path, char* dec_msg){ unsigned char* gcm_tag; - unsigned char gcm_aad[8] = {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,}; - - fp = fopen(key_path, "r"); fgets(gcm_key_hex, KEYLEN * 2 + 1, fp); @@ -463,7 +460,7 @@ int sym_decrypt(char* key_path, char* iv_path, char* enc_path, char* dec_msg){ EVP_DecryptInit(ctx, NULL, gcm_key, gcm_iv); - //EVP_DecryptUpdate(ctx, NULL, &outlen, gcm_aad, 8); + EVP_DecryptUpdate(ctx, NULL, &outlen, ad, adlen); printf("%d\n", bin_outlen); diff --git a/crypt-sym/sym.h b/crypt-sym/sym.h index 1048646..6ee0b6f 100644 --- a/crypt-sym/sym.h +++ b/crypt-sym/sym.h @@ -35,11 +35,11 @@ extern EVP_CIPHER* cipher; int sym_keygen(char* key_path, char* iv_path); -int sym_encrypt(char* key_path, char* iv_path, int enc_len, char* enc_msg, char* enc_path); +int sym_encrypt(char* key_path, char* iv_path, int enc_len, char* enc_msg, char* enc_path, char* ad); -int sym_decrypt(char* key_path, char* iv_path, char* enc_path, char* dec_msg); +int sym_decrypt(char* key_path, char* iv_path, char* enc_path, char* dec_msg, char* ad); unsigned char* gen_random_bytestream (size_t num_bytes); diff --git a/kcrypt/2025-1204.xyz.md b/kcrypt/2025-1204.xyz.md index 51d6fe6..7e3513c 100644 --- a/kcrypt/2025-1204.xyz.md +++ b/kcrypt/2025-1204.xyz.md @@ -1,4 +1,110 @@ +# compared openssl userspace api + +```c +// don't have to explicitly care about underlying buffer layout yourself +// in case of encryption... + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + EVP_EncryptInit(ctx, cipher, NULL, NULL); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, IVLEN, NULL); + EVP_EncryptInit(ctx, NULL, gcm_key, gcm_iv); + // add associated data + EVP_EncryptUpdate(ctx, NULL, &outlen, ad, adlen); + // encrypt payload + EVP_EncryptUpdate(ctx, outbuf, &outlen, enc_msg, enc_len); + EVP_EncryptFinal(ctx, outbuf, &outlen); + // get auth tag + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, TAGLEN, gcm_tag); +// and descryption... + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + EVP_DecryptInit(ctx, cipher, NULL, NULL); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, IVLEN, NULL); + EVP_DecryptInit(ctx, NULL, gcm_key, gcm_iv); + // add associated data + EVP_DecryptUpdate(ctx, NULL, &outlen, ad, adlen); + // decrypt payload + EVP_DecryptUpdate(ctx, outbuf, &outlen, inbuf_bin, bin_outlen); + // set auth tag + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, TAGLEN, gcm_tag); + EVP_DecryptFinal(ctx, outbuf, &outlen); + +``` + + +# aead comment + +```c +// https://elixir.bootlin.com/linux/v6.14/source/include/crypto/aead.h#L488 + +/** + * aead_request_set_crypt - set data buffers + * @req: request handle + * @src: source scatter / gather list + * @dst: destination scatter / gather list + * @cryptlen: number of bytes to process from @src + * @iv: IV for the cipher operation which must comply with the IV size defined + * by crypto_aead_ivsize() + * + * Setting the source data and destination data scatter / gather lists which + * hold the associated data concatenated with the plaintext or ciphertext. See + * below for the authentication tag. + * + * For encryption, the source is treated as the plaintext and the + * destination is the ciphertext. For a decryption operation, the use is + * reversed - the source is the ciphertext and the destination is the plaintext. + * + * The memory structure for cipher operation has the following structure: + * + * - AEAD encryption input: assoc data || plaintext + * - AEAD encryption output: assoc data || ciphertext || auth tag + * - AEAD decryption input: assoc data || ciphertext || auth tag + * - AEAD decryption output: assoc data || plaintext + * + * Albeit the kernel requires the presence of the AAD buffer, however, + * the kernel does not fill the AAD buffer in the output case. If the + * caller wants to have that data buffer filled, the caller must either + * use an in-place cipher operation (i.e. same memory location for + * input/output memory location). + */ + +``` + +# rfc4106 quirk? for data + +```shell +# https://datatracker.ietf.org/doc/html/rfc4106 +for aes256: + - associated data: + 8bytes in case of IPSEC without ESN + but doesn't matter as long as + we correctly align underlying buffer layout + - key: + 32bytes with 4bytes as salt at the end + - nonce: + 8 bytes +``` + +```c + u8 assoc_msg[GCM_ASSOCLEN] = { + 0x11, 0x22, 0x33, 0x44, + 0x11, 0x22, 0x33, 0x44, + 0x11, 0x22, 0x33, 0x44, + 0x11, 0x22, 0x33, 0x44, + }; + u8 nonce[GCM_NONCELEN] = { + 0x99, 0x99, 0x99, 0x99, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + u8 key[GCM_KEYLEN] = { + 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, + 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, + 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, + 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, + 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, + 0xaa, 0xbb, + 0x00, 0x00, 0x00, 0x00, + }; +``` # gcm result @@ -12,9 +118,71 @@ [ +0.000002] kcrypt: decryption completed [ +0.000001] authenticated plaintext: this is test data for kcrypt [ +37.572556] exit kcrypt +``` + +# cbc difference compared to gcm + +```c +// after encryption... +EVP_EncryptFinal(ctx, outbuf + outlen, &outlen); +// ...rather than getting tag +HMAC(EVP_sha256(), cbc_auth, KEYLEN, outbuf, outlen, result, &resultlen); + +// after decryption... +EVP_DecryptFinal(ctx, outbuf + outlen, &outlen); +// rather than setting tag +HMAC(EVP_sha256(), cbc_auth, KEYLEN, inbuf_bin, bin_outlen, result, &resultlen); ``` +# cbc comment + +```c +// https://elixir.bootlin.com/linux/v6.14/source/include/crypto/skcipher.h#L905 + +/** + * skcipher_request_set_crypt() - set data buffers + * @req: request handle + * @src: source scatter / gather list + * @dst: destination scatter / gather list + * @cryptlen: number of bytes to process from @src + * @iv: IV for the cipher operation which must comply with the IV size defined + * by crypto_skcipher_ivsize + * + * This function allows setting of the source data and destination data + * scatter / gather lists. + * + * For encryption, the source is treated as the plaintext and the + * destination is the ciphertext. For a decryption operation, the use is + * reversed - the source is the ciphertext and the destination is the plaintext. + */ + + +``` +# cbc data + +```c + u8 nonce[CBC_IVLEN] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + u8 key[32] = { + 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, + 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, + 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, + 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, + 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, + 0xaa, 0xbb, + }; + // can truncate for auth + u8 auth_val[CBC_AUTHLEN] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; +``` # cbc result -- 2.43.0