1 /*
2    BAREOS® - Backup Archiving REcovery Open Sourced
3 
4    Copyright (C) 2011-2012 Planets Communications B.V.
5    Copyright (C) 2013-2018 Bareos GmbH & Co. KG
6 
7    This program is Free Software; you can redistribute it and/or
8    modify it under the terms of version three of the GNU Affero General Public
9    License as published by the Free Software Foundation and included
10    in the file LICENSE.
11 
12    This program is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15    Affero General Public License for more details.
16 
17    You should have received a copy of the GNU Affero General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20    02110-1301, USA.
21 */
22 /*
23  * crypto_wrap.c Encryption key wrapping support functions
24  *
25  * crypto_wrap.c was based on sample code used in multiple
26  * other projects and has the following copyright:
27  *
28  * - AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
29  *
30  * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
31  *
32  * This program is free software; you can redistribute it and/or modify
33  * it under the terms of the GNU General Public License version 2 as
34  * published by the Free Software Foundation.
35  *
36  * Alternatively, this software may be distributed under the terms of BSD
37  * license.
38  *
39  * Adapted to BAREOS by Marco van Wieringen, March 2012
40  */
41 
42 #include "include/bareos.h"
43 #include "lib/crypto_wrap.h"
44 
45 #if defined(HAVE_OPENSSL)
46 
47 #  ifdef HAVE_OPENSSL
48 #    include <openssl/aes.h>
49 #  endif
50 
51 /*
52  * @kek: key encryption key (KEK)
53  * @n: length of the wrapped key in 64-bit units; e.g., 2 = 128-bit = 16 bytes
54  * @plain: plaintext key to be wrapped, n * 64 bit
55  * @cipher: wrapped key, (n + 1) * 64 bit
56  */
AesWrap(uint8_t * kek,int n,uint8_t * plain,uint8_t * cipher)57 void AesWrap(uint8_t* kek, int n, uint8_t* plain, uint8_t* cipher)
58 {
59   uint8_t *a, *r, b[16];
60   int i, j;
61 #  ifdef HAVE_OPENSSL
62   AES_KEY key;
63 #  endif
64 
65   a = cipher;
66   r = cipher + 8;
67 
68   /*
69    * 1) Initialize variables.
70    */
71   memset(a, 0xa6, 8);
72   memcpy(r, plain, 8 * n);
73 
74 #  ifdef HAVE_OPENSSL
75   AES_set_encrypt_key(kek, 128, &key);
76 #  endif
77 
78   /*
79    * 2) Calculate intermediate values.
80    * For j = 0 to 5
81    *     For i=1 to n
82    *      B = AES(K, A | R[i])
83    *      A = MSB(64, B) ^ t where t = (n*j)+i
84    *      R[i] = LSB(64, B)
85    */
86   for (j = 0; j <= 5; j++) {
87     r = cipher + 8;
88     for (i = 1; i <= n; i++) {
89       memcpy(b, a, 8);
90       memcpy(b + 8, r, 8);
91 #  ifdef HAVE_OPENSSL
92       AES_encrypt(b, b, &key);
93 #  endif
94       memcpy(a, b, 8);
95       a[7] ^= n * j + i;
96       memcpy(r, b + 8, 8);
97       r += 8;
98     }
99   }
100 
101   /* 3) Output the results.
102    *
103    * These are already in @cipher due to the location of temporary
104    * variables.
105    */
106 }
107 
108 /*
109  * @kek: key encryption key (KEK)
110  * @n: length of the wrapped key in 64-bit units; e.g., 2 = 128-bit = 16 bytes
111  * @cipher: wrapped key to be unwrapped, (n + 1) * 64 bit
112  * @plain: plaintext key, n * 64 bit
113  */
AesUnwrap(uint8_t * kek,int n,uint8_t * cipher,uint8_t * plain)114 int AesUnwrap(uint8_t* kek, int n, uint8_t* cipher, uint8_t* plain)
115 {
116   uint8_t a[8], *r, b[16];
117   int i, j;
118 #  ifdef HAVE_OPENSSL
119   AES_KEY key;
120 #  endif
121 
122   /*
123    * 1) Initialize variables.
124    */
125   memcpy(a, cipher, 8);
126   r = plain;
127   memcpy(r, cipher + 8, 8 * n);
128 
129 #  ifdef HAVE_OPENSSL
130   AES_set_decrypt_key(kek, 128, &key);
131 #  endif
132 
133   /*
134    * 2) Compute intermediate values.
135    * For j = 5 to 0
136    *     For i = n to 1
137    *      B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i
138    *      A = MSB(64, B)
139    *      R[i] = LSB(64, B)
140    */
141   for (j = 5; j >= 0; j--) {
142     r = plain + (n - 1) * 8;
143     for (i = n; i >= 1; i--) {
144       memcpy(b, a, 8);
145       b[7] ^= n * j + i;
146 
147       memcpy(b + 8, r, 8);
148 #  ifdef HAVE_OPENSSL
149       AES_decrypt(b, b, &key);
150 #  endif
151       memcpy(a, b, 8);
152       memcpy(r, b + 8, 8);
153       r -= 8;
154     }
155   }
156 
157   /*
158    * 3) Output results.
159    *
160    * These are already in @plain due to the location of temporary
161    * variables. Just verify that the IV matches with the expected value.
162    */
163   for (i = 0; i < 8; i++) {
164     if (a[i] != 0xa6) { return -1; }
165   }
166 
167   return 0;
168 }
169 #else
170 /*
171  * @kek: key encryption key (KEK)
172  * @n: length of the wrapped key in 64-bit units; e.g., 2 = 128-bit = 16 bytes
173  * @plain: plaintext key to be wrapped, n * 64 bit
174  * @cipher: wrapped key, (n + 1) * 64 bit
175  */
AesWrap(uint8_t * kek,int n,uint8_t * plain,uint8_t * cipher)176 void AesWrap(uint8_t* kek, int n, uint8_t* plain, uint8_t* cipher)
177 {
178   memcpy(cipher, plain, n * 8);
179 }
180 
181 /*
182  * @kek: key encryption key (KEK)
183  * @n: length of the wrapped key in 64-bit units; e.g., 2 = 128-bit = 16 bytes
184  * @cipher: wrapped key to be unwrapped, (n + 1) * 64 bit
185  * @plain: plaintext key, n * 64 bit
186  */
AesUnwrap(uint8_t * kek,int n,uint8_t * cipher,uint8_t * plain)187 int AesUnwrap(uint8_t* kek, int n, uint8_t* cipher, uint8_t* plain)
188 {
189   memcpy(cipher, plain, n * 8);
190   return 0;
191 }
192 #endif /* HAVE_OPENSSL */
193