-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
130 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
#include <openssl/evp.h> | ||
#include <stdint.h> | ||
#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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 */ |