1 /*
2 * Copyright 2012, 2014 Andrew Ayer
3 *
4 * This file is part of git-crypt.
5 *
6 * git-crypt is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * git-crypt is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with git-crypt. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Additional permission under GNU GPL version 3 section 7:
20 *
21 * If you modify the Program, or any covered work, by linking or
22 * combining it with the OpenSSL project's OpenSSL library (or a
23 * modified version of that library), containing parts covered by the
24 * terms of the OpenSSL or SSLeay licenses, the licensors of the Program
25 * grant you additional permission to convey the resulting work.
26 * Corresponding Source for a non-source form of such a combination
27 * shall include the source code for the parts of OpenSSL used as well
28 * as that of the covered work.
29 */
30
31 #include <openssl/opensslconf.h>
32
33 #if !defined(OPENSSL_API_COMPAT)
34
35 #include "crypto.hpp"
36 #include "key.hpp"
37 #include "util.hpp"
38 #include <openssl/aes.h>
39 #include <openssl/sha.h>
40 #include <openssl/hmac.h>
41 #include <openssl/evp.h>
42 #include <openssl/rand.h>
43 #include <openssl/err.h>
44 #include <sstream>
45 #include <cstring>
46
init_crypto()47 void init_crypto ()
48 {
49 ERR_load_crypto_strings();
50 }
51
52 struct Aes_ecb_encryptor::Aes_impl {
53 AES_KEY key;
54 };
55
Aes_ecb_encryptor(const unsigned char * raw_key)56 Aes_ecb_encryptor::Aes_ecb_encryptor (const unsigned char* raw_key)
57 : impl(new Aes_impl)
58 {
59 if (AES_set_encrypt_key(raw_key, KEY_LEN * 8, &(impl->key)) != 0) {
60 throw Crypto_error("Aes_ctr_encryptor::Aes_ctr_encryptor", "AES_set_encrypt_key failed");
61 }
62 }
63
~Aes_ecb_encryptor()64 Aes_ecb_encryptor::~Aes_ecb_encryptor ()
65 {
66 // Note: Explicit destructor necessary because class contains an unique_ptr
67 // which contains an incomplete type when the unique_ptr is declared.
68
69 explicit_memset(&impl->key, '\0', sizeof(impl->key));
70 }
71
encrypt(const unsigned char * plain,unsigned char * cipher)72 void Aes_ecb_encryptor::encrypt(const unsigned char* plain, unsigned char* cipher)
73 {
74 AES_encrypt(plain, cipher, &(impl->key));
75 }
76
77 struct Hmac_sha1_state::Hmac_impl {
78 HMAC_CTX ctx;
79 };
80
Hmac_sha1_state(const unsigned char * key,size_t key_len)81 Hmac_sha1_state::Hmac_sha1_state (const unsigned char* key, size_t key_len)
82 : impl(new Hmac_impl)
83 {
84 HMAC_Init(&(impl->ctx), key, key_len, EVP_sha1());
85 }
86
~Hmac_sha1_state()87 Hmac_sha1_state::~Hmac_sha1_state ()
88 {
89 // Note: Explicit destructor necessary because class contains an unique_ptr
90 // which contains an incomplete type when the unique_ptr is declared.
91
92 HMAC_cleanup(&(impl->ctx));
93 }
94
add(const unsigned char * buffer,size_t buffer_len)95 void Hmac_sha1_state::add (const unsigned char* buffer, size_t buffer_len)
96 {
97 HMAC_Update(&(impl->ctx), buffer, buffer_len);
98 }
99
get(unsigned char * digest)100 void Hmac_sha1_state::get (unsigned char* digest)
101 {
102 unsigned int len;
103 HMAC_Final(&(impl->ctx), digest, &len);
104 }
105
106
random_bytes(unsigned char * buffer,size_t len)107 void random_bytes (unsigned char* buffer, size_t len)
108 {
109 if (RAND_bytes(buffer, len) != 1) {
110 std::ostringstream message;
111 while (unsigned long code = ERR_get_error()) {
112 char error_string[120];
113 ERR_error_string_n(code, error_string, sizeof(error_string));
114 message << "OpenSSL Error: " << error_string << "; ";
115 }
116 throw Crypto_error("random_bytes", message.str());
117 }
118 }
119
120 #endif
121