2 * Copyright (C) 2011 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
24 * The following code is an implementation of the AES-128-CBC cipher
25 * using VIA Padlock instruction set.
28 #include <gnutls_errors.h>
29 #include <gnutls_int.h>
30 #include <gnutls/crypto.h>
31 #include <gnutls_errors.h>
35 #include <nettle/aes.h> /* for key generation in 192 and 256 bits */
36 #include <sha-padlock.h>
38 #include <aes-padlock.h>
41 aes_cipher_init (gnutls_cipher_algorithm_t algorithm, void **_ctx, int enc)
43 /* we use key size to distinguish */
44 if (algorithm != GNUTLS_CIPHER_AES_128_CBC
45 && algorithm != GNUTLS_CIPHER_AES_192_CBC
46 && algorithm != GNUTLS_CIPHER_AES_256_CBC)
47 return GNUTLS_E_INVALID_REQUEST;
49 *_ctx = gnutls_calloc (1, sizeof (struct padlock_ctx));
53 return GNUTLS_E_MEMORY_ERROR;
56 ((struct padlock_ctx *) (*_ctx))->enc = enc;
61 padlock_aes_cipher_setkey (void *_ctx, const void *userkey, size_t keysize)
63 struct padlock_ctx *ctx = _ctx;
64 struct padlock_cipher_data *pce;
69 memset (_ctx, 0, sizeof (struct padlock_cipher_data));
71 pce = ALIGN16 (&ctx->expanded_key);
73 pce->cword.b.encdec = (ctx->enc == 0);
78 pce->cword.b.ksize = 0;
79 pce->cword.b.rounds = 10;
80 memcpy (pce->ks.rd_key, userkey, 16);
81 pce->cword.b.keygen = 0;
85 pce->cword.b.ksize = 1;
86 pce->cword.b.rounds = 12;
89 pce->cword.b.ksize = 2;
90 pce->cword.b.rounds = 14;
92 /* expand key using nettle */
94 aes_set_encrypt_key (&nc, keysize, userkey);
96 aes_set_decrypt_key (&nc, keysize, userkey);
98 memcpy (pce->ks.rd_key, nc.keys, sizeof (nc.keys));
99 pce->ks.rounds = nc.nrounds;
101 pce->cword.b.keygen = 1;
105 return gnutls_assert_val (GNUTLS_E_ENCRYPTION_FAILED);
108 padlock_reload_key ();
114 aes_setiv (void *_ctx, const void *iv, size_t iv_size)
116 struct padlock_ctx *ctx = _ctx;
117 struct padlock_cipher_data *pce;
119 pce = ALIGN16 (&ctx->expanded_key);
121 memcpy (pce->iv, iv, 16);
127 padlock_aes_cbc_encrypt (void *_ctx, const void *src, size_t src_size,
128 void *dst, size_t dst_size)
130 struct padlock_ctx *ctx = _ctx;
131 struct padlock_cipher_data *pce;
133 pce = ALIGN16 (&ctx->expanded_key);
135 padlock_cbc_encrypt (dst, src, pce, src_size);
142 padlock_aes_cbc_decrypt (void *_ctx, const void *src, size_t src_size,
143 void *dst, size_t dst_size)
145 struct padlock_ctx *ctx = _ctx;
146 struct padlock_cipher_data *pcd;
148 pcd = ALIGN16 (&ctx->expanded_key);
150 padlock_cbc_encrypt (dst, src, pcd, src_size);
156 aes_deinit (void *_ctx)
161 static const gnutls_crypto_cipher_st aes_padlock_struct = {
162 .init = aes_cipher_init,
163 .setkey = padlock_aes_cipher_setkey,
165 .encrypt = padlock_aes_cbc_encrypt,
166 .decrypt = padlock_aes_cbc_decrypt,
167 .deinit = aes_deinit,
173 unsigned int edx = padlock_capability ();
175 return ((edx & (0x3 << 6)) == (0x3 << 6));
181 unsigned int edx = padlock_capability ();
183 return ((edx & (0x3 << 10)) == (0x3 << 10));
186 /* We are actually checking for SHA512 */
188 check_phe_sha512 (void)
190 unsigned int edx = padlock_capability ();
192 return ((edx & (0x3 << 25)) == (0x3 << 25));
196 check_phe_partial (void)
198 const char* text = "test and test";
199 uint32_t iv[5] = { 0x67452301UL, 0xEFCDAB89UL,
200 0x98BADCFEUL, 0x10325476UL, 0xC3D2E1F0UL };
202 padlock_sha1_blocks (iv, text, sizeof(text)-1);
203 padlock_sha1_blocks (iv, text, sizeof(text)-1);
205 if (iv[0] == 0x9096E2D8UL && iv[1] == 0xA33074EEUL &&
206 iv[2] == 0xCDBEE447UL && iv[3] == 0xEC7979D2UL &&
207 iv[4] == 0x9D3FF5CFUL)
216 unsigned int a, b, c, d;
217 gnutls_cpuid (0, &a, &b, &c, &d);
219 if ((memcmp (&b, "Cent", 4) == 0 &&
220 memcmp (&d, "aurH", 4) == 0 && memcmp (&c, "auls", 4) == 0))
229 register_padlock_crypto (void)
233 if (check_via () == 0)
235 if (check_padlock ())
237 _gnutls_debug_log ("Padlock AES accelerator was detected\n");
239 gnutls_crypto_single_cipher_register
240 (GNUTLS_CIPHER_AES_128_CBC, 80, &aes_padlock_struct);
246 /* register GCM ciphers */
248 gnutls_crypto_single_cipher_register
249 (GNUTLS_CIPHER_AES_128_GCM, 80, &aes_gcm_padlock_struct);
254 #ifdef HAVE_LIBNETTLE
256 gnutls_crypto_single_cipher_register (GNUTLS_CIPHER_AES_192_CBC,
257 80, &aes_padlock_struct);
264 gnutls_crypto_single_cipher_register (GNUTLS_CIPHER_AES_256_CBC,
265 80, &aes_padlock_struct);
272 gnutls_crypto_single_cipher_register (GNUTLS_CIPHER_AES_256_GCM,
273 80, &aes_gcm_padlock_struct);
282 #ifdef HAVE_LIBNETTLE
285 if (check_phe_partial () && phe)
287 _gnutls_debug_log ("Padlock SHA1 and SHA256 (partial) accelerator was detected\n");
288 if (check_phe_sha512 ())
290 _gnutls_debug_log ("Padlock SHA512 (partial) accelerator was detected\n");
292 gnutls_crypto_single_digest_register (GNUTLS_DIG_SHA384,
294 &sha_padlock_nano_struct);
301 gnutls_crypto_single_digest_register (GNUTLS_DIG_SHA512,
303 &sha_padlock_nano_struct);
310 gnutls_crypto_single_mac_register (GNUTLS_MAC_SHA384,
312 &hmac_sha_padlock_nano_struct);
319 gnutls_crypto_single_mac_register (GNUTLS_MAC_SHA512,
321 &hmac_sha_padlock_nano_struct);
329 gnutls_crypto_single_digest_register (GNUTLS_DIG_SHA1,
330 80, &sha_padlock_nano_struct);
337 gnutls_crypto_single_digest_register (GNUTLS_DIG_SHA224,
338 80, &sha_padlock_nano_struct);
345 gnutls_crypto_single_digest_register (GNUTLS_DIG_SHA256,
346 80, &sha_padlock_nano_struct);
353 gnutls_crypto_single_mac_register (GNUTLS_MAC_SHA1,
354 80, &hmac_sha_padlock_nano_struct);
360 /* we don't register MAC_SHA224 because it is not used by TLS */
363 gnutls_crypto_single_mac_register (GNUTLS_MAC_SHA256,
364 80, &hmac_sha_padlock_nano_struct);
372 /* Original padlock PHE. Does not support incremental operations.
374 _gnutls_debug_log ("Padlock SHA1 and SHA256 accelerator was detected\n");
376 gnutls_crypto_single_digest_register (GNUTLS_DIG_SHA1,
377 80, &sha_padlock_struct);
384 gnutls_crypto_single_digest_register (GNUTLS_DIG_SHA256,
385 80, &sha_padlock_struct);
392 gnutls_crypto_single_mac_register (GNUTLS_MAC_SHA1,
393 80, &hmac_sha_padlock_struct);
400 gnutls_crypto_single_mac_register (GNUTLS_MAC_SHA256,
401 80, &hmac_sha_padlock_struct);