}
-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;
int outlen, rv = 0;
unsigned char outbuf[MAX_OUT] = {0};
-
+ int adlen = strlen(ad);
#if CBC
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);
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);
unsigned char* gcm_iv;
- unsigned char gcm_aad[8] = {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,};
-
fp = fopen(key_path, "r");
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);
-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;
int outlen, tmplen, rv;
int bin_outlen = 0;
+ int adlen = strlen(ad);
char inbuf[MAX_OUT] = {0};
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);
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);
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);
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);
+# 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
[ +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