/
evp_encrypt.c
110 lines (92 loc) · 4.2 KB
/
evp_encrypt.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/**
@file evp_encrypt.c
@author Mitch Richling <https://www.mitchr.me/>
@Copyright Copyright 2008 by Mitch Richling. All rights reserved.
@Revision $Revision$
@SCMdate $Date$
@brief How to use OpenSSL's EVP interface to encrypt data.@EOL
@Keywords OpenSSL EVP encrypt AES
@Std C89
OpenSSL's EVP interface provides a high level, easy to
use, interface for some common cryptographic tools.
evp_encrypt.c illustrates how to do symmetric data
encryption while evp_decrypt .c illustrates how to do
symmetric data decryption.
The STDOUT of this program may be replicated with:
openssl enc -aes-256-cbc -e -nosalt \
-K 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F \
-iv 000102030405060708090A0B0C0D0E0F
*/
#include <openssl/ssl.h>
#include <openssl/bio.h>
#include <stdio.h>
#define INBUFSIZE 512
#define OUTBUFSIZE (1024*1024)
void prtErrAndExit(int eVal, char *msg);
int main(int argc, char *argv[]);
int main(int argc, char *argv[]) {
int outBytes, inBytes, tmpOutBytes, bytesInBuf, i;
int cipherBlockSize, cipherKeyLength, cipherIvLength;
unsigned char key[] = { /* Need all 32 bytes... */
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
};
unsigned char iv[] = { /* Only need 16 bytes... */
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
};
unsigned char buf2crypt[INBUFSIZE];
unsigned char outBuf[OUTBUFSIZE];
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, key, iv);
cipherBlockSize = EVP_CIPHER_CTX_block_size(&ctx);
cipherKeyLength = EVP_CIPHER_CTX_key_length(&ctx);
cipherIvLength = EVP_CIPHER_CTX_iv_length(&ctx);
fprintf(stderr, "INFO(evp_encrypt): Enc Algo: %s\n", OBJ_nid2ln(EVP_CIPHER_CTX_nid(&ctx)));
fprintf(stderr, "INFO(evp_encrypt): Key: ");
for(i=0; i<cipherKeyLength; i++)
fprintf(stderr, "%02X", (int)(key[i]));
fprintf(stderr, "\n");
fprintf(stderr, "INFO(evp_encrypt): IV: ");
for(i=0; i<cipherIvLength; i++)
fprintf(stderr, "%02X", (int)(iv[i]));
fprintf(stderr, "\n");
fprintf(stderr, "INFO(evp_encrypt): block size: %d\n", cipherBlockSize);
fprintf(stderr, "INFO(evp_encrypt): key length: %d\n", cipherKeyLength);
fprintf(stderr, "INFO(evp_encrypt): IV length: %d\n", cipherIvLength);
if((cipherKeyLength > 32) || (cipherIvLength > 16))
prtErrAndExit(1, "ERROR: Hardwired key or iv was too short!!\n");
fprintf(stderr, "INFO(evp_encrypt): READING DATA");
inBytes = outBytes = 0;
while( (bytesInBuf = fread(buf2crypt, sizeof(char), INBUFSIZE, stdin)) > 0) {
fprintf(stderr, ".");
if((OUTBUFSIZE - ((bytesInBuf + cipherBlockSize - 1) + outBytes)) <= 0)
prtErrAndExit(1, "ERROR: Buffer was not big enough to hold encrypted data!!\n");
if(!EVP_EncryptUpdate(&ctx, outBuf + outBytes, &tmpOutBytes, buf2crypt, bytesInBuf))
prtErrAndExit(1, "ERROR: EVP_EncryptUpdate didn't work...\n");
outBytes += tmpOutBytes;
inBytes += bytesInBuf;
} /* end while */
fprintf(stderr, "DONE\n");
if((OUTBUFSIZE - (cipherBlockSize + outBytes)) <= 0)
prtErrAndExit(1, "ERROR: Buffer was not big enough to hold encrypted data!!\n");
if(!EVP_EncryptFinal_ex(&ctx, outBuf+outBytes, &tmpOutBytes))
prtErrAndExit(1, "ERROR: EVP_EncryptFinal_ex didn't work...\n");
outBytes += tmpOutBytes;
fprintf(stderr, "INFO(evp_encrypt): Bytes in: %d\n", inBytes);
fprintf(stderr, "INFO(evp_encrypt): Bytes out: %d\n", outBytes);
EVP_CIPHER_CTX_cleanup(&ctx);
fwrite(outBuf, 1, outBytes, stdout);
return 1;
} /* end func main */
/* Save some vertical space with this simple error handling function.. */
void prtErrAndExit(int eVal, char *msg) {
if(msg != NULL)
fprintf(stderr, "INFO(evp_encrypt): %s\n\n", msg);
exit(eVal);
} /* end func prtErrAndExit */