#include #include #include char *base64_encode(const unsigned char *data, size_t input_length, size_t *output_length); int IX_aes_256_gcm_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *aad, int aad_len, unsigned char *key, unsigned char *iv, unsigned char *ciphertext, unsigned char *tag) { EVP_CIPHER_CTX *ctx = NULL; int len; int ciphertext_len; /* Create and initialise the context */ if(!(ctx = EVP_CIPHER_CTX_new())) goto err_exit; /* Initialise the encryption operation. */ if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL)) goto err_exit; /* Set IV length if default 12 bytes (96 bits) is not appropriate */ // if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 16, NULL)) // goto err_exit; /* Initialise key and IV */ if(1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) goto err_exit; /* Provide any AAD data. This can be called zero or more times as * required */ if(1 != EVP_EncryptUpdate(ctx, NULL, &len, aad, aad_len)) goto err_exit; /* 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)) goto err_exit; 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)) goto err_exit; ciphertext_len += len; /* Get the tag */ if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag)) goto err_exit; /* Clean up */ EVP_CIPHER_CTX_free(ctx); ctx = NULL; return ciphertext_len; err_exit: if (ctx) EVP_CIPHER_CTX_free(ctx); return -1; } enum mkt_state {MKTS_PLAIN_LINE, MKTS_ENC_LINE, MKTS_INVALID}; static const char* mkt_ctrl[] = {"PLAIN-START", "CRYPT-START", NULL}; static enum mkt_state mkt_state_get(const char* ctrl) { enum mkt_state state; if (ctrl==NULL) return MKTS_INVALID; for (state = MKTS_PLAIN_LINE; state < MKTS_INVALID; state++) { if (strcmp(ctrl, mkt_ctrl[state])==0) return state; } return MKTS_INVALID; } // how to call: mktoken mysecretkey "PLAIN-START" "unencrypted-line" "unencrypted-line" ... "CRYPT-START" "encrypted-line""encrypted-line" // e.g. mktoken mysecret PLAIN-START "n=httpname" "u=username" "e=1427896580" CRYPT-START "secpar=hidden" static int ifc_do_mktoken(int argc, char **argv) { char* textu = malloc(1); //will hold unencrypted lines terminated with \n and concetenated char* texte = malloc(1); //will hold encrypted lines terminated with \n and concetenated int writeEncrypted = 0; int ctext_len = 0; static enum mkt_state mkts = MKTS_INVALID; if (!textu || !texte) { fprintf(stdout, "ERROR:mem_alloc_error1\n"); return 255; } textu[0]=0; texte[0]=0; int argidx=1; char* secret = (argidx URL-friendly ! static char *decoding_table = NULL; static size_t mod_table[] = {0, 2, 1}; char *base64_encode(const unsigned char *data, size_t input_length, size_t *output_length) { *output_length = 4 * ((input_length + 2) / 3); char *encoded_data = (char*)malloc(*output_length+1); if (encoded_data == NULL) return NULL; size_t i,j; for (i = 0, j = 0; i < input_length;) { unsigned int octet_a = i < input_length ? data[i++] : 0; unsigned int octet_b = i < input_length ? data[i++] : 0; unsigned int octet_c = i < input_length ? data[i++] : 0; unsigned int triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c; encoded_data[j++] = encoding_table[(triple >> 3 * 6) & 0x3F]; encoded_data[j++] = encoding_table[(triple >> 2 * 6) & 0x3F]; encoded_data[j++] = encoding_table[(triple >> 1 * 6) & 0x3F]; encoded_data[j++] = encoding_table[(triple >> 0 * 6) & 0x3F]; } for (i = 0; i < mod_table[input_length % 3]; i++) encoded_data[*output_length - 1 - i] = 0; encoded_data[*output_length]=0; return encoded_data; }