Coverage Report

Created: 2023-03-26 08:33

/src/gnutls/lib/accelerated/x86/x86-common.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2011-2018 Free Software Foundation, Inc.
3
 * Copyright (C) 2018 Red Hat, Inc.
4
 *
5
 * Author: Nikos Mavrogiannopoulos
6
 *
7
 * This file is part of GnuTLS.
8
 *
9
 * The GnuTLS is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public License
11
 * as published by the Free Software Foundation; either version 2.1 of
12
 * the License, or (at your option) any later version.
13
 *
14
 * This library is distributed in the hope that it will be useful, but
15
 * WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
21
 *
22
 */
23
24
/*
25
 * The following code is an implementation of the AES-128-CBC cipher
26
 * using intel's AES instruction set. 
27
 */
28
29
#include "errors.h"
30
#include "gnutls_int.h"
31
#include <gnutls/crypto.h>
32
#include "errors.h"
33
#include <aes-x86.h>
34
#include <sha-x86.h>
35
#include <x86-common.h>
36
#ifdef HAVE_LIBNETTLE
37
# include <nettle/aes.h>  /* for key generation in 192 and 256 bits */
38
# include <sha-padlock.h>
39
#endif
40
#include <aes-padlock.h>
41
#ifdef HAVE_CPUID_H
42
# include <cpuid.h>
43
#else
44
# define __get_cpuid(...) 0
45
# define __get_cpuid_count(...) 0
46
#endif
47
48
/* ebx, ecx, edx 
49
 * This is a format compatible with openssl's CPUID detection.
50
 */
51
#if defined(__GNUC__)
52
__attribute__((visibility("hidden")))
53
#elif defined(__SUNPRO_C)
54
__hidden
55
#endif
56
unsigned int GNUTLS_x86_cpuid_s[4];
57
58
#ifndef bit_SHA
59
# define bit_SHA (1<<29)
60
#endif
61
62
/* ecx */
63
#ifndef bit_AVX512BITALG
64
# define bit_AVX512BITALG 0x4000
65
#endif
66
67
#ifndef bit_PCLMUL
68
# define bit_PCLMUL 0x2
69
#endif
70
71
#ifndef bit_SSSE3
72
/* ecx */
73
# define bit_SSSE3 0x0000200
74
#endif
75
76
#ifndef bit_AES
77
# define bit_AES 0x2000000
78
#endif
79
80
#ifndef bit_AVX
81
# define bit_AVX 0x10000000
82
#endif
83
84
#ifndef bit_AVX2
85
# define bit_AVX2 0x00000020
86
#endif
87
88
#ifndef bit_AVX512F
89
# define bit_AVX512F 0x00010000
90
#endif
91
92
#ifndef bit_AVX512IFMA
93
# define bit_AVX512IFMA 0x00200000
94
#endif
95
96
#ifndef bit_AVX512BW
97
# define bit_AVX512BW 0x40000000
98
#endif
99
100
#ifndef bit_AVX512VL
101
# define bit_AVX512VL 0x80000000
102
#endif
103
104
#ifndef bit_OSXSAVE
105
# define bit_OSXSAVE 0x8000000
106
#endif
107
108
#ifndef bit_MOVBE
109
# define bit_MOVBE 0x00400000
110
#endif
111
112
0
#define bit_PADLOCK (0x3 << 6)
113
0
#define bit_PADLOCK_PHE (0x3 << 10)
114
0
#define bit_PADLOCK_PHE_SHA512 (0x3 << 25)
115
116
/* Our internal bit-string for cpu capabilities. Should be set
117
 * in GNUTLS_CPUID_OVERRIDE */
118
0
#define EMPTY_SET 1
119
0
#define INTEL_AES_NI (1<<1)
120
0
#define INTEL_SSSE3 (1<<2)
121
0
#define INTEL_PCLMUL (1<<3)
122
0
#define INTEL_AVX (1<<4)
123
0
#define INTEL_SHA (1<<5)
124
0
#define PADLOCK (1<<20)
125
0
#define PADLOCK_PHE (1<<21)
126
0
#define PADLOCK_PHE_SHA512 (1<<22)
127
128
#ifndef HAVE_GET_CPUID_COUNT
129
static inline void
130
get_cpuid_level7(unsigned int *eax, unsigned int *ebx,
131
     unsigned int *ecx, unsigned int *edx)
132
{
133
  /* we avoid using __get_cpuid_count, because it is not available with gcc 4.8 */
134
  if (__get_cpuid_max(7, 0) < 7)
135
    return;
136
137
  __cpuid_count(7, 0, *eax, *ebx, *ecx, *edx);
138
  return;
139
}
140
#else
141
20
# define get_cpuid_level7(a,b,c,d) __get_cpuid_count(7, 0, a, b, c, d)
142
#endif
143
144
static unsigned read_cpuid_vals(unsigned int vals[4])
145
20
{
146
20
  unsigned t1, t2, t3;
147
20
  vals[0] = vals[1] = vals[2] = vals[3] = 0;
148
149
20
  if (!__get_cpuid(1, &t1, &t2, &vals[1], &vals[0]))
150
0
    return 0;
151
  /* suppress AVX512; it works conditionally on certain CPUs on the original code */
152
20
  vals[1] &= 0xfffff7ff;
153
154
20
  get_cpuid_level7(&t1, &vals[2], &t2, &t3);
155
156
20
  return 1;
157
20
}
158
159
/* Based on the example in "How to detect New Instruction support in
160
 * the 4th generation Intel Core processor family.
161
 * https://software.intel.com/en-us/articles/how-to-detect-new-instruction-support-in-the-4th-generation-intel-core-processor-family
162
 */
163
static unsigned check_4th_gen_intel_features(unsigned ecx)
164
20
{
165
20
  uint32_t xcr0;
166
167
20
  if ((ecx & bit_OSXSAVE) != bit_OSXSAVE)
168
0
    return 0;
169
170
#if defined(_MSC_VER) && !defined(__clang__)
171
  xcr0 = _xgetbv(0);
172
#else
173
20
 __asm__("xgetbv": "=a"(xcr0): "c"(0):"%edx");
174
20
#endif
175
  /* Check if xmm and ymm state are enabled in XCR0. */
176
20
  return (xcr0 & 6) == 6;
177
20
}
178
179
static void capabilities_to_intel_cpuid(unsigned capabilities)
180
0
{
181
0
  unsigned a[4];
182
183
0
  if (capabilities & EMPTY_SET) {
184
0
    return;
185
0
  }
186
187
0
  if (!read_cpuid_vals(a))
188
0
    return;
189
190
0
  if (capabilities & INTEL_AES_NI) {
191
0
    if (a[1] & bit_AES) {
192
0
      GNUTLS_x86_cpuid_s[1] |= bit_AES;
193
0
    } else {
194
0
      _gnutls_debug_log
195
0
          ("AESNI acceleration requested but not available\n");
196
0
    }
197
0
  }
198
199
0
  if (capabilities & INTEL_SSSE3) {
200
0
    if (a[1] & bit_SSSE3) {
201
0
      GNUTLS_x86_cpuid_s[1] |= bit_SSSE3;
202
0
    } else {
203
0
      _gnutls_debug_log
204
0
          ("SSSE3 acceleration requested but not available\n");
205
0
    }
206
0
  }
207
208
0
  if (capabilities & INTEL_AVX) {
209
0
    if ((a[1] & bit_AVX) && (a[1] & bit_MOVBE) &&
210
0
        check_4th_gen_intel_features(a[1])) {
211
0
      GNUTLS_x86_cpuid_s[1] |= bit_AVX | bit_MOVBE;
212
0
    } else {
213
0
      _gnutls_debug_log
214
0
          ("AVX acceleration requested but not available\n");
215
0
    }
216
0
  }
217
218
0
  if (capabilities & INTEL_PCLMUL) {
219
0
    if (a[1] & bit_PCLMUL) {
220
0
      GNUTLS_x86_cpuid_s[1] |= bit_PCLMUL;
221
0
    } else {
222
0
      _gnutls_debug_log
223
0
          ("PCLMUL acceleration requested but not available\n");
224
0
    }
225
0
  }
226
227
0
  if (capabilities & INTEL_SHA) {
228
0
    if (a[2] & bit_SHA) {
229
0
      GNUTLS_x86_cpuid_s[2] |= bit_SHA;
230
0
    } else {
231
0
      _gnutls_debug_log
232
0
          ("SHA acceleration requested but not available\n");
233
0
    }
234
0
  }
235
0
}
236
237
static unsigned check_optimized_aes(void)
238
20
{
239
20
  return (GNUTLS_x86_cpuid_s[1] & bit_AES);
240
20
}
241
242
static unsigned check_ssse3(void)
243
20
{
244
20
  return (GNUTLS_x86_cpuid_s[1] & bit_SSSE3);
245
20
}
246
247
static unsigned check_sha(void)
248
40
{
249
40
  return (GNUTLS_x86_cpuid_s[2] & bit_SHA);
250
40
}
251
252
#ifdef ASM_X86_64
253
static unsigned check_avx_movbe(void)
254
20
{
255
20
  return (GNUTLS_x86_cpuid_s[1] & (bit_AVX | bit_MOVBE)) ==
256
20
      (bit_AVX | bit_MOVBE);
257
20
}
258
259
static unsigned check_pclmul(void)
260
20
{
261
20
  return (GNUTLS_x86_cpuid_s[1] & bit_PCLMUL);
262
20
}
263
#endif
264
265
#ifdef ENABLE_PADLOCK
266
static unsigned capabilities_to_zhaoxin_edx(unsigned capabilities)
267
0
{
268
0
  unsigned a, b, c, t;
269
270
0
  if (capabilities & EMPTY_SET) {
271
0
    return 0;
272
0
  }
273
274
0
  if (!__get_cpuid(1, &t, &a, &b, &c))
275
0
    return 0;
276
0
  if (capabilities & PADLOCK) {
277
0
    if (c & bit_PADLOCK) {
278
0
      GNUTLS_x86_cpuid_s[2] |= bit_PADLOCK;
279
0
    } else {
280
0
      _gnutls_debug_log
281
0
          ("Padlock acceleration requested but not available\n");
282
0
    }
283
0
  }
284
285
0
  if (capabilities & PADLOCK_PHE) {
286
0
    if (c & bit_PADLOCK_PHE) {
287
0
      GNUTLS_x86_cpuid_s[2] |= bit_PADLOCK_PHE;
288
0
    } else {
289
0
      _gnutls_debug_log
290
0
          ("Padlock-PHE acceleration requested but not available\n");
291
0
    }
292
0
  }
293
294
0
  if (capabilities & PADLOCK_PHE_SHA512) {
295
0
    if (c & bit_PADLOCK_PHE_SHA512) {
296
0
      GNUTLS_x86_cpuid_s[2] |= bit_PADLOCK_PHE_SHA512;
297
0
    } else {
298
0
      _gnutls_debug_log
299
0
          ("Padlock-PHE-SHA512 acceleration requested but not available\n");
300
0
    }
301
0
  }
302
303
0
  return GNUTLS_x86_cpuid_s[2];
304
0
}
305
306
static int check_padlock(unsigned edx)
307
0
{
308
0
  return ((edx & bit_PADLOCK) == bit_PADLOCK);
309
0
}
310
311
static int check_phe(unsigned edx)
312
0
{
313
0
  return ((edx & bit_PADLOCK_PHE) == bit_PADLOCK_PHE);
314
0
}
315
316
/* We are actually checking for SHA512 */
317
static int check_phe_sha512(unsigned edx)
318
0
{
319
0
  return ((edx & bit_PADLOCK_PHE_SHA512) == bit_PADLOCK_PHE_SHA512);
320
0
}
321
322
/* On some of the Zhaoxin CPUs, pclmul has a faster acceleration effect */
323
static int check_fast_pclmul(void)
324
0
{
325
0
  unsigned int a, b, c, d;
326
0
  unsigned int family, model;
327
328
0
  if (!__get_cpuid(1, &a, &b, &c, &d))
329
0
    return 0;
330
331
0
  family = ((a >> 8) & 0x0F);
332
0
  model = ((a >> 4) & 0x0F) + ((a >> 12) & 0xF0);
333
334
0
  if (((family == 0x6) && (model == 0xf || model == 0x19)) ||
335
0
      ((family == 0x7) && (model == 0x1B || model == 0x3B)))
336
0
    return 1;
337
0
  else
338
0
    return 0;
339
0
}
340
341
static int check_phe_partial(void)
342
0
{
343
0
  const char text[64] =
344
0
      "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
345
0
      "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
346
0
  uint32_t iv[5] = { 0x67452301UL, 0xEFCDAB89UL,
347
0
    0x98BADCFEUL, 0x10325476UL, 0xC3D2E1F0UL
348
0
  };
349
350
  /* If EAX is set to -1 (this is the case with padlock_sha1_blocks), the
351
   * xsha1 instruction takes a complete SHA-1 block (64 bytes), while it
352
   * takes arbitrary length data otherwise. */
353
0
  padlock_sha1_blocks(iv, text, 1);
354
355
0
  if (iv[0] == 0xDA4968EBUL && iv[1] == 0x2E377C1FUL &&
356
0
      iv[2] == 0x884E8F52UL && iv[3] == 0x83524BEBUL &&
357
0
      iv[4] == 0xE74EBDBDUL)
358
0
    return 1;
359
0
  else
360
0
    return 0;
361
0
}
362
363
static unsigned check_zhaoxin(void)
364
20
{
365
20
  unsigned int a, b, c, d;
366
367
20
  if (!__get_cpuid(0, &a, &b, &c, &d))
368
0
    return 0;
369
370
  /* Zhaoxin and VIA CPU was detected */
371
20
  if ((memcmp(&b, "Cent", 4) == 0 &&
372
20
       memcmp(&d, "aurH", 4) == 0 &&
373
20
       memcmp(&c, "auls", 4) == 0) ||
374
20
      (memcmp(&b, "  Sh", 4) == 0 &&
375
20
       memcmp(&d, "angh", 4) == 0 && memcmp(&c, "ai  ", 4) == 0)) {
376
0
    return 1;
377
0
  }
378
379
20
  return 0;
380
20
}
381
382
static
383
void register_x86_padlock_crypto(unsigned capabilities)
384
20
{
385
20
  int ret, phe;
386
20
  unsigned edx;
387
388
20
  if (check_zhaoxin() == 0)
389
20
    return;
390
391
0
  memset(GNUTLS_x86_cpuid_s, 0, sizeof(GNUTLS_x86_cpuid_s));
392
393
0
  if (capabilities == 0) {
394
0
    if (!read_cpuid_vals(GNUTLS_x86_cpuid_s))
395
0
      return;
396
0
    edx = padlock_capability();
397
0
  } else {
398
0
    capabilities_to_intel_cpuid(capabilities);
399
0
    edx = capabilities_to_zhaoxin_edx(capabilities);
400
0
  }
401
402
0
  if (check_ssse3()) {
403
0
    _gnutls_debug_log("Zhaoxin SSSE3 was detected\n");
404
405
0
    ret =
406
0
        gnutls_crypto_single_cipher_register
407
0
        (GNUTLS_CIPHER_AES_128_GCM, 90,
408
0
         &_gnutls_aes_gcm_x86_ssse3, 0);
409
0
    if (ret < 0) {
410
0
      gnutls_assert();
411
0
    }
412
413
0
    ret =
414
0
        gnutls_crypto_single_cipher_register
415
0
        (GNUTLS_CIPHER_AES_192_GCM, 90,
416
0
         &_gnutls_aes_gcm_x86_ssse3, 0);
417
0
    if (ret < 0) {
418
0
      gnutls_assert();
419
0
    }
420
421
0
    ret =
422
0
        gnutls_crypto_single_cipher_register
423
0
        (GNUTLS_CIPHER_AES_256_GCM, 90,
424
0
         &_gnutls_aes_gcm_x86_ssse3, 0);
425
0
    if (ret < 0) {
426
0
      gnutls_assert();
427
0
    }
428
429
0
    ret =
430
0
        gnutls_crypto_single_cipher_register
431
0
        (GNUTLS_CIPHER_AES_128_CBC, 90, &_gnutls_aes_ssse3, 0);
432
0
    if (ret < 0) {
433
0
      gnutls_assert();
434
0
    }
435
436
0
    ret =
437
0
        gnutls_crypto_single_cipher_register
438
0
        (GNUTLS_CIPHER_AES_192_CBC, 90, &_gnutls_aes_ssse3, 0);
439
0
    if (ret < 0) {
440
0
      gnutls_assert();
441
0
    }
442
443
0
    ret =
444
0
        gnutls_crypto_single_cipher_register
445
0
        (GNUTLS_CIPHER_AES_256_CBC, 90, &_gnutls_aes_ssse3, 0);
446
0
    if (ret < 0) {
447
0
      gnutls_assert();
448
0
    }
449
0
  }
450
451
0
  if (check_sha() || check_ssse3()) {
452
0
    if (check_sha())
453
0
      _gnutls_debug_log("Zhaoxin SHA was detected\n");
454
455
0
    ret =
456
0
        gnutls_crypto_single_digest_register(GNUTLS_DIG_SHA1,
457
0
               80,
458
0
               &_gnutls_sha_x86_ssse3,
459
0
               0);
460
0
    if (ret < 0) {
461
0
      gnutls_assert();
462
0
    }
463
464
0
    ret =
465
0
        gnutls_crypto_single_digest_register(GNUTLS_DIG_SHA224,
466
0
               80,
467
0
               &_gnutls_sha_x86_ssse3,
468
0
               0);
469
0
    if (ret < 0) {
470
0
      gnutls_assert();
471
0
    }
472
473
0
    ret =
474
0
        gnutls_crypto_single_digest_register(GNUTLS_DIG_SHA256,
475
0
               80,
476
0
               &_gnutls_sha_x86_ssse3,
477
0
               0);
478
0
    if (ret < 0) {
479
0
      gnutls_assert();
480
0
    }
481
482
0
    ret =
483
0
        gnutls_crypto_single_mac_register(GNUTLS_MAC_SHA1,
484
0
                  80,
485
0
                  &_gnutls_hmac_sha_x86_ssse3,
486
0
                  0);
487
0
    if (ret < 0)
488
0
      gnutls_assert();
489
490
0
    ret =
491
0
        gnutls_crypto_single_mac_register(GNUTLS_MAC_SHA224,
492
0
                  80,
493
0
                  &_gnutls_hmac_sha_x86_ssse3,
494
0
                  0);
495
0
    if (ret < 0)
496
0
      gnutls_assert();
497
498
0
    ret =
499
0
        gnutls_crypto_single_mac_register(GNUTLS_MAC_SHA256,
500
0
                  80,
501
0
                  &_gnutls_hmac_sha_x86_ssse3,
502
0
                  0);
503
0
    if (ret < 0)
504
0
      gnutls_assert();
505
506
0
    ret =
507
0
        gnutls_crypto_single_digest_register(GNUTLS_DIG_SHA384,
508
0
               80,
509
0
               &_gnutls_sha_x86_ssse3,
510
0
               0);
511
0
    if (ret < 0)
512
0
      gnutls_assert();
513
514
0
    ret =
515
0
        gnutls_crypto_single_digest_register(GNUTLS_DIG_SHA512,
516
0
               80,
517
0
               &_gnutls_sha_x86_ssse3,
518
0
               0);
519
0
    if (ret < 0)
520
0
      gnutls_assert();
521
0
    ret =
522
0
        gnutls_crypto_single_mac_register(GNUTLS_MAC_SHA384,
523
0
                  80,
524
0
                  &_gnutls_hmac_sha_x86_ssse3,
525
0
                  0);
526
0
    if (ret < 0)
527
0
      gnutls_assert();
528
529
0
    ret =
530
0
        gnutls_crypto_single_mac_register(GNUTLS_MAC_SHA512,
531
0
                  80,
532
0
                  &_gnutls_hmac_sha_x86_ssse3,
533
0
                  0);
534
0
    if (ret < 0)
535
0
      gnutls_assert();
536
0
  }
537
538
0
  if (check_optimized_aes()) {
539
0
    _gnutls_debug_log("Zhaoxin AES accelerator was detected\n");
540
0
    ret =
541
0
        gnutls_crypto_single_cipher_register
542
0
        (GNUTLS_CIPHER_AES_128_CBC, 80, &_gnutls_aesni_x86, 0);
543
0
    if (ret < 0) {
544
0
      gnutls_assert();
545
0
    }
546
547
0
    ret =
548
0
        gnutls_crypto_single_cipher_register
549
0
        (GNUTLS_CIPHER_AES_192_CBC, 80, &_gnutls_aesni_x86, 0);
550
0
    if (ret < 0) {
551
0
      gnutls_assert();
552
0
    }
553
554
0
    ret =
555
0
        gnutls_crypto_single_cipher_register
556
0
        (GNUTLS_CIPHER_AES_256_CBC, 80, &_gnutls_aesni_x86, 0);
557
0
    if (ret < 0) {
558
0
      gnutls_assert();
559
0
    }
560
561
0
    ret =
562
0
        gnutls_crypto_single_cipher_register
563
0
        (GNUTLS_CIPHER_AES_128_CCM, 80,
564
0
         &_gnutls_aes_ccm_x86_aesni, 0);
565
0
    if (ret < 0) {
566
0
      gnutls_assert();
567
0
    }
568
569
0
    ret =
570
0
        gnutls_crypto_single_cipher_register
571
0
        (GNUTLS_CIPHER_AES_256_CCM, 80,
572
0
         &_gnutls_aes_ccm_x86_aesni, 0);
573
0
    if (ret < 0) {
574
0
      gnutls_assert();
575
0
    }
576
577
0
    ret =
578
0
        gnutls_crypto_single_cipher_register
579
0
        (GNUTLS_CIPHER_AES_128_CCM_8, 80,
580
0
         &_gnutls_aes_ccm_x86_aesni, 0);
581
0
    if (ret < 0) {
582
0
      gnutls_assert();
583
0
    }
584
585
0
    ret =
586
0
        gnutls_crypto_single_cipher_register
587
0
        (GNUTLS_CIPHER_AES_256_CCM_8, 80,
588
0
         &_gnutls_aes_ccm_x86_aesni, 0);
589
0
    if (ret < 0) {
590
0
      gnutls_assert();
591
0
    }
592
593
0
    ret =
594
0
        gnutls_crypto_single_cipher_register
595
0
        (GNUTLS_CIPHER_AES_128_XTS, 80,
596
0
         &_gnutls_aes_xts_x86_aesni, 0);
597
0
    if (ret < 0) {
598
0
      gnutls_assert();
599
0
    }
600
601
0
    ret =
602
0
        gnutls_crypto_single_cipher_register
603
0
        (GNUTLS_CIPHER_AES_256_XTS, 80,
604
0
         &_gnutls_aes_xts_x86_aesni, 0);
605
0
    if (ret < 0) {
606
0
      gnutls_assert();
607
0
    }
608
609
0
# ifdef ASM_X86_64
610
0
    if (check_pclmul()) {
611
      /* register GCM ciphers */
612
0
      _gnutls_debug_log
613
0
          ("Zhaoxin GCM accelerator was detected\n");
614
0
      if (check_avx_movbe() && check_fast_pclmul()) {
615
0
        _gnutls_debug_log
616
0
            ("Zhaoxin GCM accelerator (AVX) was detected\n");
617
0
        ret =
618
0
            gnutls_crypto_single_cipher_register
619
0
            (GNUTLS_CIPHER_AES_128_GCM, 80,
620
0
             &_gnutls_aes_gcm_pclmul_avx, 0);
621
0
        if (ret < 0) {
622
0
          gnutls_assert();
623
0
        }
624
625
0
        ret =
626
0
            gnutls_crypto_single_cipher_register
627
0
            (GNUTLS_CIPHER_AES_192_GCM, 80,
628
0
             &_gnutls_aes_gcm_pclmul_avx, 0);
629
0
        if (ret < 0) {
630
0
          gnutls_assert();
631
0
        }
632
633
0
        ret =
634
0
            gnutls_crypto_single_cipher_register
635
0
            (GNUTLS_CIPHER_AES_256_GCM, 80,
636
0
             &_gnutls_aes_gcm_pclmul_avx, 0);
637
0
        if (ret < 0) {
638
0
          gnutls_assert();
639
0
        }
640
0
      } else {
641
0
        ret =
642
0
            gnutls_crypto_single_cipher_register
643
0
            (GNUTLS_CIPHER_AES_128_GCM, 80,
644
0
             &_gnutls_aes_gcm_pclmul, 0);
645
0
        if (ret < 0) {
646
0
          gnutls_assert();
647
0
        }
648
649
0
        ret =
650
0
            gnutls_crypto_single_cipher_register
651
0
            (GNUTLS_CIPHER_AES_192_GCM, 80,
652
0
             &_gnutls_aes_gcm_pclmul, 0);
653
0
        if (ret < 0) {
654
0
          gnutls_assert();
655
0
        }
656
657
0
        ret =
658
0
            gnutls_crypto_single_cipher_register
659
0
            (GNUTLS_CIPHER_AES_256_GCM, 80,
660
0
             &_gnutls_aes_gcm_pclmul, 0);
661
0
        if (ret < 0) {
662
0
          gnutls_assert();
663
0
        }
664
0
      }
665
0
    } else
666
0
# endif
667
0
    {
668
0
      ret =
669
0
          gnutls_crypto_single_cipher_register
670
0
          (GNUTLS_CIPHER_AES_128_GCM, 80,
671
0
           &_gnutls_aes_gcm_x86_aesni, 0);
672
0
      if (ret < 0) {
673
0
        gnutls_assert();
674
0
      }
675
676
0
      ret =
677
0
          gnutls_crypto_single_cipher_register
678
0
          (GNUTLS_CIPHER_AES_192_GCM, 80,
679
0
           &_gnutls_aes_gcm_x86_aesni, 0);
680
0
      if (ret < 0) {
681
0
        gnutls_assert();
682
0
      }
683
684
0
      ret =
685
0
          gnutls_crypto_single_cipher_register
686
0
          (GNUTLS_CIPHER_AES_256_GCM, 80,
687
0
           &_gnutls_aes_gcm_x86_aesni, 0);
688
0
      if (ret < 0) {
689
0
        gnutls_assert();
690
0
      }
691
0
    }
692
0
  }
693
694
0
  if (check_padlock(edx)) {
695
0
    _gnutls_debug_log("Padlock AES accelerator was detected\n");
696
0
    ret =
697
0
        gnutls_crypto_single_cipher_register
698
0
        (GNUTLS_CIPHER_AES_128_CBC, 80, &_gnutls_aes_padlock, 0);
699
0
    if (ret < 0) {
700
0
      gnutls_assert();
701
0
    }
702
703
0
    ret =
704
0
        gnutls_crypto_single_cipher_register
705
0
        (GNUTLS_CIPHER_AES_192_CBC, 80, &_gnutls_aes_padlock, 0);
706
0
    if (ret < 0) {
707
0
      gnutls_assert();
708
0
    }
709
710
    /* register GCM ciphers */
711
0
    ret =
712
0
        gnutls_crypto_single_cipher_register
713
0
        (GNUTLS_CIPHER_AES_128_GCM, 90,
714
0
         &_gnutls_aes_gcm_padlock, 0);
715
0
    if (ret < 0) {
716
0
      gnutls_assert();
717
0
    }
718
719
0
    ret =
720
0
        gnutls_crypto_single_cipher_register
721
0
        (GNUTLS_CIPHER_AES_256_CBC, 80, &_gnutls_aes_padlock, 0);
722
0
    if (ret < 0) {
723
0
      gnutls_assert();
724
0
    }
725
726
0
    ret =
727
0
        gnutls_crypto_single_cipher_register
728
0
        (GNUTLS_CIPHER_AES_256_GCM, 90,
729
0
         &_gnutls_aes_gcm_padlock, 0);
730
0
    if (ret < 0) {
731
0
      gnutls_assert();
732
0
    }
733
0
  }
734
735
0
  if (!check_optimized_aes() && !check_padlock(edx))
736
0
    _gnutls_priority_update_non_aesni();
737
738
0
# ifdef HAVE_LIBNETTLE
739
0
  phe = check_phe(edx);
740
741
0
  if (phe && check_phe_partial()) {
742
0
    _gnutls_debug_log
743
0
        ("Padlock SHA1 and SHA256 (partial) accelerator was detected\n");
744
0
    if (check_phe_sha512(edx)) {
745
0
      _gnutls_debug_log
746
0
          ("Padlock SHA512 (partial) accelerator was detected\n");
747
0
      ret =
748
0
          gnutls_crypto_single_digest_register
749
0
          (GNUTLS_DIG_SHA384, 80, &_gnutls_sha_padlock, 0);
750
0
      if (ret < 0) {
751
0
        gnutls_assert();
752
0
      }
753
754
0
      ret =
755
0
          gnutls_crypto_single_digest_register
756
0
          (GNUTLS_DIG_SHA512, 80, &_gnutls_sha_padlock, 0);
757
0
      if (ret < 0) {
758
0
        gnutls_assert();
759
0
      }
760
761
0
      ret =
762
0
          gnutls_crypto_single_mac_register
763
0
          (GNUTLS_MAC_SHA384, 80,
764
0
           &_gnutls_hmac_sha_padlock, 0);
765
0
      if (ret < 0) {
766
0
        gnutls_assert();
767
0
      }
768
769
0
      ret =
770
0
          gnutls_crypto_single_mac_register
771
0
          (GNUTLS_MAC_SHA512, 80,
772
0
           &_gnutls_hmac_sha_padlock, 0);
773
0
      if (ret < 0) {
774
0
        gnutls_assert();
775
0
      }
776
0
    }
777
778
0
    ret =
779
0
        gnutls_crypto_single_digest_register(GNUTLS_DIG_SHA1,
780
0
               90,
781
0
               &_gnutls_sha_padlock,
782
0
               0);
783
0
    if (ret < 0) {
784
0
      gnutls_assert();
785
0
    }
786
787
0
    ret =
788
0
        gnutls_crypto_single_digest_register(GNUTLS_DIG_SHA224,
789
0
               90,
790
0
               &_gnutls_sha_padlock,
791
0
               0);
792
0
    if (ret < 0) {
793
0
      gnutls_assert();
794
0
    }
795
796
0
    ret =
797
0
        gnutls_crypto_single_digest_register(GNUTLS_DIG_SHA256,
798
0
               90,
799
0
               &_gnutls_sha_padlock,
800
0
               0);
801
0
    if (ret < 0) {
802
0
      gnutls_assert();
803
0
    }
804
805
0
    ret =
806
0
        gnutls_crypto_single_mac_register(GNUTLS_MAC_SHA1,
807
0
                  90,
808
0
                  &_gnutls_hmac_sha_padlock,
809
0
                  0);
810
0
    if (ret < 0) {
811
0
      gnutls_assert();
812
0
    }
813
814
    /* we don't register MAC_SHA224 because it is not used by TLS */
815
816
0
    ret =
817
0
        gnutls_crypto_single_mac_register(GNUTLS_MAC_SHA256,
818
0
                  90,
819
0
                  &_gnutls_hmac_sha_padlock,
820
0
                  0);
821
0
    if (ret < 0) {
822
0
      gnutls_assert();
823
0
    }
824
0
  } else if (phe) {
825
    /* Original padlock PHE. Does not support incremental operations.
826
     */
827
0
    _gnutls_debug_log
828
0
        ("Padlock SHA1 and SHA256 accelerator was detected\n");
829
0
    ret =
830
0
        gnutls_crypto_single_digest_register(GNUTLS_DIG_SHA1,
831
0
               90,
832
0
               &_gnutls_sha_padlock_oneshot,
833
0
               0);
834
0
    if (ret < 0) {
835
0
      gnutls_assert();
836
0
    }
837
838
0
    ret =
839
0
        gnutls_crypto_single_digest_register(GNUTLS_DIG_SHA256,
840
0
               90,
841
0
               &_gnutls_sha_padlock_oneshot,
842
0
               0);
843
0
    if (ret < 0) {
844
0
      gnutls_assert();
845
0
    }
846
847
0
    ret =
848
0
        gnutls_crypto_single_mac_register(GNUTLS_MAC_SHA1,
849
0
                  90,
850
0
                  &_gnutls_hmac_sha_padlock_oneshot,
851
0
                  0);
852
0
    if (ret < 0) {
853
0
      gnutls_assert();
854
0
    }
855
856
0
    ret =
857
0
        gnutls_crypto_single_mac_register(GNUTLS_MAC_SHA256,
858
0
                  90,
859
0
                  &_gnutls_hmac_sha_padlock_oneshot,
860
0
                  0);
861
0
    if (ret < 0) {
862
0
      gnutls_assert();
863
0
    }
864
0
  }
865
0
# endif
866
867
0
  return;
868
0
}
869
#endif
870
871
enum x86_cpu_vendor {
872
  X86_CPU_VENDOR_OTHER,
873
  X86_CPU_VENDOR_INTEL,
874
  X86_CPU_VENDOR_AMD,
875
};
876
877
static enum x86_cpu_vendor check_x86_cpu_vendor(void)
878
20
{
879
20
  unsigned int a, b, c, d;
880
881
20
  if (!__get_cpuid(0, &a, &b, &c, &d)) {
882
0
    return X86_CPU_VENDOR_OTHER;
883
0
  }
884
885
20
  if (memcmp(&b, "Genu", 4) == 0 &&
886
20
      memcmp(&d, "ineI", 4) == 0 && memcmp(&c, "ntel", 4) == 0) {
887
0
    return X86_CPU_VENDOR_INTEL;
888
0
  }
889
890
20
  if (memcmp(&b, "Auth", 4) == 0 &&
891
20
      memcmp(&d, "enti", 4) == 0 && memcmp(&c, "cAMD", 4) == 0) {
892
20
    return X86_CPU_VENDOR_AMD;
893
20
  }
894
895
0
  return X86_CPU_VENDOR_OTHER;
896
20
}
897
898
static
899
void register_x86_intel_crypto(unsigned capabilities)
900
20
{
901
20
  int ret;
902
20
  enum x86_cpu_vendor vendor;
903
904
20
  memset(GNUTLS_x86_cpuid_s, 0, sizeof(GNUTLS_x86_cpuid_s));
905
906
20
  vendor = check_x86_cpu_vendor();
907
20
  if (vendor == X86_CPU_VENDOR_OTHER) {
908
0
    return;
909
0
  }
910
911
20
  if (capabilities == 0) {
912
20
    if (!read_cpuid_vals(GNUTLS_x86_cpuid_s))
913
0
      return;
914
20
    if (!check_4th_gen_intel_features(GNUTLS_x86_cpuid_s[1])) {
915
0
      GNUTLS_x86_cpuid_s[1] &= ~bit_AVX;
916
917
      /* Clear AVX2 bits as well, according to what
918
       * OpenSSL does.  Should we clear
919
       * bit_AVX512DQ, bit_AVX512PF, bit_AVX512ER,
920
       * and bit_AVX512CD? */
921
0
      GNUTLS_x86_cpuid_s[2] &= ~(bit_AVX2 |
922
0
               bit_AVX512F |
923
0
               bit_AVX512IFMA |
924
0
               bit_AVX512BW | bit_AVX512BW);
925
0
    }
926
20
  } else {
927
0
    capabilities_to_intel_cpuid(capabilities);
928
0
  }
929
930
  /* CRYPTOGAMS uses the (1 << 30) bit as an indicator of Intel CPUs */
931
20
  if (vendor == X86_CPU_VENDOR_INTEL) {
932
0
    GNUTLS_x86_cpuid_s[0] |= 1 << 30;
933
20
  } else {
934
20
    GNUTLS_x86_cpuid_s[0] &= ~(1 << 30);
935
20
  }
936
937
20
  if (check_ssse3()) {
938
20
    _gnutls_debug_log("Intel SSSE3 was detected\n");
939
940
20
    ret =
941
20
        gnutls_crypto_single_cipher_register
942
20
        (GNUTLS_CIPHER_AES_128_GCM, 90,
943
20
         &_gnutls_aes_gcm_x86_ssse3, 0);
944
20
    if (ret < 0) {
945
0
      gnutls_assert();
946
0
    }
947
948
20
    ret =
949
20
        gnutls_crypto_single_cipher_register
950
20
        (GNUTLS_CIPHER_AES_192_GCM, 90,
951
20
         &_gnutls_aes_gcm_x86_ssse3, 0);
952
20
    if (ret < 0) {
953
0
      gnutls_assert();
954
0
    }
955
956
20
    ret =
957
20
        gnutls_crypto_single_cipher_register
958
20
        (GNUTLS_CIPHER_AES_256_GCM, 90,
959
20
         &_gnutls_aes_gcm_x86_ssse3, 0);
960
20
    if (ret < 0) {
961
0
      gnutls_assert();
962
0
    }
963
964
20
    ret =
965
20
        gnutls_crypto_single_cipher_register
966
20
        (GNUTLS_CIPHER_AES_128_CBC, 90, &_gnutls_aes_ssse3, 0);
967
20
    if (ret < 0) {
968
0
      gnutls_assert();
969
0
    }
970
971
20
    ret =
972
20
        gnutls_crypto_single_cipher_register
973
20
        (GNUTLS_CIPHER_AES_192_CBC, 90, &_gnutls_aes_ssse3, 0);
974
20
    if (ret < 0) {
975
0
      gnutls_assert();
976
0
    }
977
978
20
    ret =
979
20
        gnutls_crypto_single_cipher_register
980
20
        (GNUTLS_CIPHER_AES_256_CBC, 90, &_gnutls_aes_ssse3, 0);
981
20
    if (ret < 0) {
982
0
      gnutls_assert();
983
0
    }
984
20
  }
985
986
20
  if (check_sha() || check_ssse3()) {
987
20
    if (check_sha())
988
20
      _gnutls_debug_log("Intel SHA was detected\n");
989
990
20
    ret =
991
20
        gnutls_crypto_single_digest_register(GNUTLS_DIG_SHA1,
992
20
               80,
993
20
               &_gnutls_sha_x86_ssse3,
994
20
               0);
995
20
    if (ret < 0) {
996
0
      gnutls_assert();
997
0
    }
998
999
20
    ret =
1000
20
        gnutls_crypto_single_digest_register(GNUTLS_DIG_SHA224,
1001
20
               80,
1002
20
               &_gnutls_sha_x86_ssse3,
1003
20
               0);
1004
20
    if (ret < 0) {
1005
0
      gnutls_assert();
1006
0
    }
1007
1008
20
    ret =
1009
20
        gnutls_crypto_single_digest_register(GNUTLS_DIG_SHA256,
1010
20
               80,
1011
20
               &_gnutls_sha_x86_ssse3,
1012
20
               0);
1013
20
    if (ret < 0) {
1014
0
      gnutls_assert();
1015
0
    }
1016
1017
20
    ret =
1018
20
        gnutls_crypto_single_mac_register(GNUTLS_MAC_SHA1,
1019
20
                  80,
1020
20
                  &_gnutls_hmac_sha_x86_ssse3,
1021
20
                  0);
1022
20
    if (ret < 0)
1023
20
      gnutls_assert();
1024
1025
20
    ret =
1026
20
        gnutls_crypto_single_mac_register(GNUTLS_MAC_SHA224,
1027
20
                  80,
1028
20
                  &_gnutls_hmac_sha_x86_ssse3,
1029
20
                  0);
1030
20
    if (ret < 0)
1031
20
      gnutls_assert();
1032
1033
20
    ret =
1034
20
        gnutls_crypto_single_mac_register(GNUTLS_MAC_SHA256,
1035
20
                  80,
1036
20
                  &_gnutls_hmac_sha_x86_ssse3,
1037
20
                  0);
1038
20
    if (ret < 0)
1039
20
      gnutls_assert();
1040
1041
20
    ret =
1042
20
        gnutls_crypto_single_digest_register(GNUTLS_DIG_SHA384,
1043
20
               80,
1044
20
               &_gnutls_sha_x86_ssse3,
1045
20
               0);
1046
20
    if (ret < 0)
1047
20
      gnutls_assert();
1048
1049
20
    ret =
1050
20
        gnutls_crypto_single_digest_register(GNUTLS_DIG_SHA512,
1051
20
               80,
1052
20
               &_gnutls_sha_x86_ssse3,
1053
20
               0);
1054
20
    if (ret < 0)
1055
20
      gnutls_assert();
1056
20
    ret =
1057
20
        gnutls_crypto_single_mac_register(GNUTLS_MAC_SHA384,
1058
20
                  80,
1059
20
                  &_gnutls_hmac_sha_x86_ssse3,
1060
20
                  0);
1061
20
    if (ret < 0)
1062
20
      gnutls_assert();
1063
1064
20
    ret =
1065
20
        gnutls_crypto_single_mac_register(GNUTLS_MAC_SHA512,
1066
20
                  80,
1067
20
                  &_gnutls_hmac_sha_x86_ssse3,
1068
20
                  0);
1069
20
    if (ret < 0)
1070
20
      gnutls_assert();
1071
20
  }
1072
1073
20
  if (check_optimized_aes()) {
1074
20
    _gnutls_debug_log("Intel AES accelerator was detected\n");
1075
20
    ret =
1076
20
        gnutls_crypto_single_cipher_register
1077
20
        (GNUTLS_CIPHER_AES_128_CBC, 80, &_gnutls_aesni_x86, 0);
1078
20
    if (ret < 0) {
1079
0
      gnutls_assert();
1080
0
    }
1081
1082
20
    ret =
1083
20
        gnutls_crypto_single_cipher_register
1084
20
        (GNUTLS_CIPHER_AES_192_CBC, 80, &_gnutls_aesni_x86, 0);
1085
20
    if (ret < 0) {
1086
0
      gnutls_assert();
1087
0
    }
1088
1089
20
    ret =
1090
20
        gnutls_crypto_single_cipher_register
1091
20
        (GNUTLS_CIPHER_AES_256_CBC, 80, &_gnutls_aesni_x86, 0);
1092
20
    if (ret < 0) {
1093
0
      gnutls_assert();
1094
0
    }
1095
1096
20
    ret =
1097
20
        gnutls_crypto_single_cipher_register
1098
20
        (GNUTLS_CIPHER_AES_128_CCM, 80,
1099
20
         &_gnutls_aes_ccm_x86_aesni, 0);
1100
20
    if (ret < 0) {
1101
0
      gnutls_assert();
1102
0
    }
1103
1104
20
    ret =
1105
20
        gnutls_crypto_single_cipher_register
1106
20
        (GNUTLS_CIPHER_AES_256_CCM, 80,
1107
20
         &_gnutls_aes_ccm_x86_aesni, 0);
1108
20
    if (ret < 0) {
1109
0
      gnutls_assert();
1110
0
    }
1111
1112
20
    ret =
1113
20
        gnutls_crypto_single_cipher_register
1114
20
        (GNUTLS_CIPHER_AES_128_CCM_8, 80,
1115
20
         &_gnutls_aes_ccm_x86_aesni, 0);
1116
20
    if (ret < 0) {
1117
0
      gnutls_assert();
1118
0
    }
1119
1120
20
    ret =
1121
20
        gnutls_crypto_single_cipher_register
1122
20
        (GNUTLS_CIPHER_AES_256_CCM_8, 80,
1123
20
         &_gnutls_aes_ccm_x86_aesni, 0);
1124
20
    if (ret < 0) {
1125
0
      gnutls_assert();
1126
0
    }
1127
1128
20
    ret =
1129
20
        gnutls_crypto_single_cipher_register
1130
20
        (GNUTLS_CIPHER_AES_128_XTS, 80,
1131
20
         &_gnutls_aes_xts_x86_aesni, 0);
1132
20
    if (ret < 0) {
1133
0
      gnutls_assert();
1134
0
    }
1135
1136
20
    ret =
1137
20
        gnutls_crypto_single_cipher_register
1138
20
        (GNUTLS_CIPHER_AES_256_XTS, 80,
1139
20
         &_gnutls_aes_xts_x86_aesni, 0);
1140
20
    if (ret < 0) {
1141
0
      gnutls_assert();
1142
0
    }
1143
1144
20
#ifdef ASM_X86_64
1145
20
    if (check_pclmul()) {
1146
      /* register GCM ciphers */
1147
20
      if (check_avx_movbe()) {
1148
20
        _gnutls_debug_log
1149
20
            ("Intel GCM accelerator (AVX) was detected\n");
1150
20
        ret =
1151
20
            gnutls_crypto_single_cipher_register
1152
20
            (GNUTLS_CIPHER_AES_128_GCM, 80,
1153
20
             &_gnutls_aes_gcm_pclmul_avx, 0);
1154
20
        if (ret < 0) {
1155
0
          gnutls_assert();
1156
0
        }
1157
1158
20
        ret =
1159
20
            gnutls_crypto_single_cipher_register
1160
20
            (GNUTLS_CIPHER_AES_192_GCM, 80,
1161
20
             &_gnutls_aes_gcm_pclmul_avx, 0);
1162
20
        if (ret < 0) {
1163
0
          gnutls_assert();
1164
0
        }
1165
1166
20
        ret =
1167
20
            gnutls_crypto_single_cipher_register
1168
20
            (GNUTLS_CIPHER_AES_256_GCM, 80,
1169
20
             &_gnutls_aes_gcm_pclmul_avx, 0);
1170
20
        if (ret < 0) {
1171
0
          gnutls_assert();
1172
0
        }
1173
20
      } else {
1174
0
        _gnutls_debug_log
1175
0
            ("Intel GCM accelerator was detected\n");
1176
0
        ret =
1177
0
            gnutls_crypto_single_cipher_register
1178
0
            (GNUTLS_CIPHER_AES_128_GCM, 80,
1179
0
             &_gnutls_aes_gcm_pclmul, 0);
1180
0
        if (ret < 0) {
1181
0
          gnutls_assert();
1182
0
        }
1183
1184
0
        ret =
1185
0
            gnutls_crypto_single_cipher_register
1186
0
            (GNUTLS_CIPHER_AES_192_GCM, 80,
1187
0
             &_gnutls_aes_gcm_pclmul, 0);
1188
0
        if (ret < 0) {
1189
0
          gnutls_assert();
1190
0
        }
1191
1192
0
        ret =
1193
0
            gnutls_crypto_single_cipher_register
1194
0
            (GNUTLS_CIPHER_AES_256_GCM, 80,
1195
0
             &_gnutls_aes_gcm_pclmul, 0);
1196
0
        if (ret < 0) {
1197
0
          gnutls_assert();
1198
0
        }
1199
0
      }
1200
20
    } else
1201
0
#endif
1202
0
    {
1203
0
      ret =
1204
0
          gnutls_crypto_single_cipher_register
1205
0
          (GNUTLS_CIPHER_AES_128_GCM, 80,
1206
0
           &_gnutls_aes_gcm_x86_aesni, 0);
1207
0
      if (ret < 0) {
1208
0
        gnutls_assert();
1209
0
      }
1210
1211
0
      ret =
1212
0
          gnutls_crypto_single_cipher_register
1213
0
          (GNUTLS_CIPHER_AES_192_GCM, 80,
1214
0
           &_gnutls_aes_gcm_x86_aesni, 0);
1215
0
      if (ret < 0) {
1216
0
        gnutls_assert();
1217
0
      }
1218
1219
0
      ret =
1220
0
          gnutls_crypto_single_cipher_register
1221
0
          (GNUTLS_CIPHER_AES_256_GCM, 80,
1222
0
           &_gnutls_aes_gcm_x86_aesni, 0);
1223
0
      if (ret < 0) {
1224
0
        gnutls_assert();
1225
0
      }
1226
0
    }
1227
20
  } else {
1228
0
    _gnutls_priority_update_non_aesni();
1229
0
  }
1230
1231
20
  return;
1232
20
}
1233
1234
void register_x86_crypto(void)
1235
20
{
1236
20
  unsigned capabilities = 0;
1237
20
  char *p;
1238
20
  p = secure_getenv("GNUTLS_CPUID_OVERRIDE");
1239
20
  if (p) {
1240
0
    capabilities = strtol(p, NULL, 0);
1241
0
  }
1242
1243
20
  register_x86_intel_crypto(capabilities);
1244
20
#ifdef ENABLE_PADLOCK
1245
20
  register_x86_padlock_crypto(capabilities);
1246
20
#endif
1247
20
}