dav/crypto.c

changeset 5
88625853ae74
child 9
6aec77cfa95b
equal deleted inserted replaced
4:ae5a98f0545c 5:88625853ae74
1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 2013 Olaf Wintermann. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include "crypto.h"
34
35 AESDecrypter* aes_decrypter_new(Key *key, void *stream, dav_write_func write_func) {
36 AESDecrypter *dec = malloc(sizeof(AESDecrypter));
37 dec->stream = stream;
38 dec->write = write_func;
39
40 EVP_CIPHER_CTX_init(&dec->ctx);
41 if(key->type == KEY_AES128) {
42 EVP_DecryptInit_ex(&dec->ctx, EVP_aes_128_cbc(), NULL, key->data, NULL);
43 } else if(key->type == KEY_AES256) {
44 EVP_DecryptInit_ex(&dec->ctx, EVP_aes_256_cbc(), NULL, key->data, NULL);
45 } else {
46 fprintf(stderr, "unknown key type\n");
47 exit(-1);
48 }
49 return dec;
50 }
51
52 size_t aes_write(const void *buf, size_t s, size_t n, AESDecrypter *dec) {
53 int len = s*n;
54 int outlen = len + AES_BLOCK_SIZE;
55 unsigned char *out = malloc(outlen);
56 EVP_DecryptUpdate(&dec->ctx, out, &len, buf, len);
57 dec->write(out, 1, len, dec->stream);
58 free(out);
59 return (s*n) / s;
60 }
61
62 void aes_decrypter_close(AESDecrypter *dec) {
63 void *out = malloc(128);
64 int len = 0;
65 EVP_DecryptFinal_ex(&dec->ctx, out, &len);
66 dec->write(out, 1, len, dec->stream);
67 free(out);
68 EVP_CIPHER_CTX_cleanup(&dec->ctx);
69 free(dec);
70 }
71
72
73 AESEncrypter* aes_encrypter_new(Key *key, void *stream, dav_read_func read_func) {
74 AESEncrypter *enc = malloc(sizeof(AESEncrypter));
75 enc->stream = stream;
76 enc->read = read_func;
77 enc->tmp = NULL;
78 enc->tmplen = 0;
79 enc->tmpoff = 0;
80 enc->end = 0;
81
82 EVP_CIPHER_CTX_init(&enc->ctx);
83 if(key->type == KEY_AES128) {
84 EVP_EncryptInit_ex(&enc->ctx, EVP_aes_128_cbc(), NULL, key->data, NULL);
85 } else if(key->type == KEY_AES256) {
86 EVP_EncryptInit_ex(&enc->ctx, EVP_aes_256_cbc(), NULL, key->data, NULL);
87 } else {
88 fprintf(stderr, "unknown key type\n");
89 exit(-1);
90 }
91 return enc;
92 }
93
94 size_t aes_read(void *buf, size_t s, size_t n, AESEncrypter *enc) {
95 size_t len = s*n;
96 if(enc->tmp) {
97 size_t tmp_diff = enc->tmplen - enc->tmpoff;
98 size_t cp_len = tmp_diff > len ? len : tmp_diff;
99 memcpy(buf, enc->tmp + enc->tmpoff, cp_len);
100 enc->tmpoff += cp_len;
101 if(enc->tmpoff >= enc->tmplen) {
102 free(enc->tmp);
103 enc->tmp = NULL;
104 enc->tmplen = 0;
105 enc->tmpoff = 0;
106 }
107 return cp_len / s;
108 }
109
110 if(enc->end) {
111 return 0;
112 }
113
114 void *in = malloc(len);
115 size_t in_len = enc->read(in, 1, len, enc->stream);
116
117 void *out = NULL;
118 int outlen = 0;
119 if(in_len != 0) {
120 outlen = len + AES_BLOCK_SIZE;
121 out = malloc(outlen);
122 EVP_EncryptUpdate(&enc->ctx, out, &outlen, in, in_len);
123 //out = (char*)aes_encrypt(enc->ctx, (unsigned char*)in, (int*)&in_len);
124 } else {
125 out = malloc(AES_BLOCK_SIZE);
126 EVP_EncryptFinal_ex(&enc->ctx, out, &outlen);
127 enc->end = 1;
128 }
129 enc->tmp = out;
130 enc->tmplen = outlen;
131 enc->tmpoff = 0;
132
133 return aes_read(buf, s, n, enc);
134 }
135
136 void aes_encrypter_close(AESEncrypter *enc) {
137 if(enc->tmp) {
138 free(enc->tmp);
139 }
140 EVP_CIPHER_CTX_cleanup(&enc->ctx);
141 free(enc);
142 }

mercurial