-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcrypto.c
154 lines (121 loc) · 4.56 KB
/
crypto.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include <stdio.h>
#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <string.h>
#include "crypto.h"
#define IV_LENGTH 16 //FIXME: double check
#define SALT "12345678"
void init_opensll() {
/* Initialise the library */
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
if (CONF_modules_load_file(NULL, NULL, 0) <= 0) {
fprintf(stderr, "FATAL: error loading configuration file\n");
ERR_print_errors_fp(stderr);
exit(1);
}
}
//password MUST BE '\0' terminated
//saltBuffer MUST BE 8 bytes
//the input buffer doesn't have to have any data in it, it can be null
//returns 0 if success, -1 otherwise
//must be at the start of file
int startEncryption(CryptoState_t *state, const char *password) {
/* get the key, iv and salt*/
memcpy(state->salt, SALT, strlen(SALT));
EVP_BytesToKey(EVP_aes_128_cbc(), EVP_sha1(), state->salt,
(const unsigned char *) password, strlen(password), 4, state->key, state->iv);
if (!(state->ctx = EVP_CIPHER_CTX_new()))
return -1;
if (EVP_EncryptInit_ex(state->ctx, EVP_aes_128_cbc(), NULL, state->key,
state->iv) != 1)
return -1;
//printf("Key: %s iv: %s\n", state->key, state->iv);
return 0;
}
//0 if success, -1 otherwise
//The amount of data written depends on the block alignment of the encrypted data:
//as a result the amount of data written may be anything from zero bytes to (inl + cipher_block_size - 1) so outl should contain sufficient room.
int updateEncryption(CryptoState_t *state, const char *inputBuffer,
const int inputBufferSize, char *outputBuffer, int *outputDataSize) {
if (EVP_EncryptUpdate(state->ctx, (unsigned char *) outputBuffer,
outputDataSize, (unsigned char *) inputBuffer,
inputBufferSize) != 1) {
return -1;
}
return 0;
}
//we (optionally) call EVP_EncryptUpdate one more time because it can make it easier to use these functions in loops
//0 if success, -1 otherwise
int finishEncryption(CryptoState_t *state, const char *inputBuffer,
const int inputBufferSize, char *outputBuffer, int *outputDataSize) {
int dataSentSoFar = 0, tempint;
//update one last time
if (inputBufferSize > 0) {
if (EVP_EncryptUpdate(state->ctx, (unsigned char *) outputBuffer,
&dataSentSoFar, (unsigned char *) inputBuffer,
inputBufferSize) != 1) {
printf("error\n");
return -1;
}
}
unsigned char * currPos = (unsigned char *) outputBuffer + dataSentSoFar;
if (EVP_EncryptFinal_ex(state->ctx, currPos, &tempint)
!= 1)
return -1;
*outputDataSize = dataSentSoFar + tempint;
/* Clean up */
//EVP_CIPHER_CTX_free(state->ctx);
return 0;
}
//0 if success, -1 otherwise
int startDecryption(CryptoState_t *state, const char *password, const char *iv) {
/* get the key, iv and salt*/
memcpy(state->salt, SALT, strlen(SALT));
EVP_BytesToKey(EVP_aes_128_cbc(), EVP_sha1(), state->salt,
(const unsigned char *) password, strlen(password), 4, state->key, state->iv);
/* copy the salt and iv */
if (iv != NULL) {
memcpy(state->iv, iv, IV_LENGTH);
}
/* init all the stuff */
if (!(state->ctx = EVP_CIPHER_CTX_new()))
return -1;
if (EVP_DecryptInit_ex(state->ctx, EVP_aes_128_cbc(), NULL,
state->key, state->iv) != 1)
return -1;
//printf("Key: %s iv: %s\n", state->key, state->iv);
return 0;
}
//0 if success, -1 otherwise
//if padding is enabled the decrypted data buffer out passed to EVP_DecryptUpdate() should have sufficient room for (inl + cipher_block_size) bytes
int updateDecryption(CryptoState_t *state, const char *inputBuffer,
const int inputBufferSize, char *outputBuffer, int *outputDataSize) {
if (EVP_DecryptUpdate(state->ctx, (unsigned char *) outputBuffer,
outputDataSize, (unsigned char *) inputBuffer, inputBufferSize) != 1)
return -1;
return 0;
}
//we (optionally) call EVP_DecryptUpdate one more time because it can make it easier to use these functions in loops
//0 if success, -1 otherwise
int finishDecryption(CryptoState_t *state, const char *inputBuffer,
const int inputBufferSize, char *outputBuffer, int *outputDataSize) {
int dataSentSoFar = 0, tempint;
//check if we have any data waiting to be decrypted
if (inputBufferSize > 0) {
if (EVP_DecryptUpdate(state->ctx, (unsigned char *) outputBuffer,
&dataSentSoFar, (unsigned char *) inputBuffer, inputBufferSize) != 1)
return -1;
}
if (EVP_DecryptFinal_ex(state->ctx, (unsigned char *) outputBuffer,
&tempint) != 1) {
printf("error when calling final decrypt\n");
return -1;
}
printf("done with the final decryption, the data: %d\n", tempint);
*outputDataSize = dataSentSoFar + tempint;
/* Clean up */
//EVP_CIPHER_CTX_free(state->ctx);
return 0;
}