From 60cfb19d9068e50179a9ebfd3838c13647aeaa89 Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Thu, 23 Nov 2023 20:31:23 -0500 Subject: [PATCH] crypto.c: add AES GCM 128 en/decryption --- lib/crypto.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/crypto.h | 11 ++++++- 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/lib/crypto.c b/lib/crypto.c index dc140e4..09344ad 100644 --- a/lib/crypto.c +++ b/lib/crypto.c @@ -262,6 +262,87 @@ void x25519_derive_secret(unsigned char secret[X25519_KEY_SIZE], const x25519_ke EVP_PKEY_CTX_free(pctx); } +// GCM AES 128 + +int gcm_encrypt(const unsigned char *plaintext, int plaintext_len, unsigned char *ciphertext, + unsigned char *key, unsigned char *iv, unsigned char *tag) +{ + EVP_CIPHER_CTX *ctx; + + int len; + + int ciphertext_len; + + if(!(ctx = EVP_CIPHER_CTX_new())) + handle_error(__func__); + + if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL)) + handle_error(__func__); + + if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 16, NULL)) + handle_error(__func__); + + if(1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) + handle_error(__func__); + + if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len)) + handle_error(__func__); + ciphertext_len = len; + + if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) + handle_error(__func__); + ciphertext_len += len; + + if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag)) + handle_error(__func__); + + EVP_CIPHER_CTX_free(ctx); + + return ciphertext_len; +} + +int gcm_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *plaintext, + unsigned char *key, unsigned char *iv, unsigned char *tag) +{ + EVP_CIPHER_CTX *ctx; + int len; + int plaintext_len; + int ret; + + if(!(ctx = EVP_CIPHER_CTX_new())) + handle_error(__func__); + + if(!EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL)) + handle_error(__func__); + + if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 16, NULL)) + handle_error(__func__); + + if(!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) + handle_error(__func__); + + if(!EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len)) + handle_error(__func__); + plaintext_len = len; + + if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag)) + handle_error(__func__); + + ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len); + + EVP_CIPHER_CTX_free(ctx); + + if(ret > 0) { + /* Success */ + plaintext_len += len; + return plaintext_len; + } else { + /* Verify failed */ + printf("failed\n"); + return -1; + } +} + // ED25519 struct ed25519_key_s { diff --git a/lib/crypto.h b/lib/crypto.h index 13c5f28..d00b3dd 100644 --- a/lib/crypto.h +++ b/lib/crypto.h @@ -16,6 +16,8 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * modified by fduncanh 2023 */ /* @@ -64,9 +66,16 @@ x25519_key_t *x25519_key_generate(void); x25519_key_t *x25519_key_from_raw(const unsigned char data[X25519_KEY_SIZE]); void x25519_key_get_raw(unsigned char data[X25519_KEY_SIZE], const x25519_key_t *key); void x25519_key_destroy(x25519_key_t *key); - +int get_random_bytes(unsigned char *buf, int num); + void x25519_derive_secret(unsigned char secret[X25519_KEY_SIZE], const x25519_key_t *ours, const x25519_key_t *theirs); +// GCM AES 128 + +int gcm_encrypt(const unsigned char *plaintext, int plaintext_len, unsigned char *ciphertext, + unsigned char *key, unsigned char *iv, unsigned char *tag); +int gcm_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *plaintext, + unsigned char *key, unsigned char *iv, unsigned char *tag); // ED25519 #define ED25519_KEY_SIZE 32