diff --git a/isv_app/crypto.cpp b/isv_app/crypto.cpp new file mode 100644 index 0000000..7f8a99b --- /dev/null +++ b/isv_app/crypto.cpp @@ -0,0 +1,119 @@ +#include +#include +#include "crypto.h" +void handleErrors(){ + printf("There was a terrible error!\n"); +} + +int decrypt(uint8_t *key, uint8_t *ciphertext, int ciphertext_len, uint8_t *plaintext, uint8_t *iv, int iv_len, uint8_t *aad, + int aad_len, uint8_t *tag) +{ + EVP_CIPHER_CTX *ctx; + int len; + int plaintext_len; + int ret; + + /* Create and initialise the context */ + if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors(); + + /* Initialise the decryption operation. */ + if(!EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL)) + handleErrors(); + + /* Set IV length. Not necessary if this is 12 bytes (96 bits) */ + if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv_len, NULL)) + handleErrors(); + + /* Initialise key and IV */ + if(!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) handleErrors(); + /* Provide any AAD data. This can be called zero or more times as + * required + */ + /*if(!EVP_DecryptUpdate(ctx, NULL, &len, aad, aad_len)) + handleErrors();*/ + + /* Provide the message to be decrypted, and obtain the plaintext output. + * EVP_DecryptUpdate can be called multiple times if necessary + */ + if(!EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len)) + handleErrors(); + plaintext_len = len; + + /* Set expected tag value. Works in OpenSSL 1.0.1d and later */ + if((tag != NULL) && (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag))) + handleErrors(); + + /* Finalise the decryption. A positive return value indicates success, + * anything else is a failure - the plaintext is not trustworthy. + */ + ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len); + + /* Clean up */ + EVP_CIPHER_CTX_free(ctx); + + if(ret > 0) + { + /* Success */ + plaintext_len += len; + return plaintext_len; + } + else + { + /* Verify failed */ + return -1; + } +} + + +int encrypt(uint8_t *key, uint8_t *plaintext, int plaintext_len, uint8_t *ciphertext, uint8_t *iv, int iv_len, uint8_t *aad, + int aad_len, uint8_t *tag) +{ + EVP_CIPHER_CTX *ctx; + + int len; + + int ciphertext_len; + + + /* Create and initialise the context */ + if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors(); + + /* Initialise the encryption operation. */ + if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL)) + handleErrors(); + + /* Set IV length if default 12 bytes (96 bits) is not appropriate */ + if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv_len, NULL)) + handleErrors(); + + /* Initialise key and IV */ + if(1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) handleErrors(); + + /* Provide any AAD data. This can be called zero or more times as + * required + */ +/* if(1 != EVP_EncryptUpdate(ctx, NULL, &len, aad, aad_len)) + handleErrors();*/ + + /* Provide the message to be encrypted, and obtain the encrypted output. + * EVP_EncryptUpdate can be called multiple times if necessary + */ + if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len)) + handleErrors(); + ciphertext_len = len; + + /* Finalise the encryption. Normally ciphertext bytes may be written at + * this stage, but this does not occur in GCM mode + */ + if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) handleErrors(); + ciphertext_len += len; + + /* Get the tag */ + if((tag != NULL) && (1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag))) + handleErrors(); + + /* Clean up */ + EVP_CIPHER_CTX_free(ctx); + + return ciphertext_len; +} diff --git a/isv_app/crypto.h b/isv_app/crypto.h new file mode 100644 index 0000000..f98e243 --- /dev/null +++ b/isv_app/crypto.h @@ -0,0 +1,11 @@ +#ifndef CRYPTO_H +#define CRYPTO_H + +int decrypt(uint8_t *key, uint8_t *ciphertext, int ciphertext_len, uint8_t *plaintext, uint8_t *iv, int iv_len, uint8_t *aad, + int aad_len, uint8_t *tag); + +int encrypt(uint8_t *key, uint8_t *plaintext, int plaintext_len, uint8_t *ciphertext, uint8_t *iv, int iv_len, uint8_t *aad, + int aad_len, uint8_t *tag); + +void handleErrors(); +#endif /* CRYPTO_H */