Coverage Report

Created: 2025-03-18 06:55

/src/gnutls/lib/accelerated/x86/aes-xts-x86-aesni.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2011-2012 Free Software Foundation, Inc.
3
 * Copyright (C) 2020 Red Hat, Inc.
4
 *
5
 * Authors: Nikos Mavrogiannopoulos, Anderson Toshiyuki Sasaki
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 wraps the CRYPTOGAMS implementation of the AES-XTS cipher
26
 * using Intel's AES instruction set.
27
 */
28
29
#include "errors.h"
30
#include "gnutls_int.h"
31
#include "fips.h"
32
#include <gnutls/crypto.h>
33
#include "aes-x86.h"
34
#include "x86-common.h"
35
36
struct x86_aes_xts_ctx {
37
  AES_KEY block_key;
38
  AES_KEY tweak_key;
39
  uint8_t iv[16];
40
  int enc;
41
};
42
43
static int x86_aes_xts_cipher_init(gnutls_cipher_algorithm_t algorithm,
44
           void **_ctx, int enc)
45
0
{
46
0
  if (algorithm != GNUTLS_CIPHER_AES_128_XTS &&
47
0
      algorithm != GNUTLS_CIPHER_AES_256_XTS)
48
0
    return GNUTLS_E_INVALID_REQUEST;
49
50
0
  *_ctx = gnutls_calloc(1, sizeof(struct x86_aes_xts_ctx));
51
0
  if (*_ctx == NULL) {
52
0
    gnutls_assert();
53
0
    return GNUTLS_E_MEMORY_ERROR;
54
0
  }
55
56
0
  ((struct x86_aes_xts_ctx *)(*_ctx))->enc = enc;
57
58
0
  return 0;
59
0
}
60
61
static int x86_aes_xts_cipher_setkey(void *_ctx, const void *userkey,
62
             size_t keysize)
63
0
{
64
0
  struct x86_aes_xts_ctx *ctx = _ctx;
65
0
  int ret;
66
0
  size_t keybits;
67
0
  const uint8_t *key = userkey;
68
69
0
  if ((keysize != 32) && (keysize != 64))
70
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
71
72
  /* Check key block according to FIPS-140-2 IG A.9 */
73
0
  if (_gnutls_fips_mode_enabled()) {
74
0
    if (gnutls_memcmp(key, key + (keysize / 2), keysize / 2) == 0) {
75
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
76
0
    }
77
0
  }
78
79
  /* Size in bits of each half for block and tweak (=keysize * 8 / 2) */
80
0
  keybits = keysize * 4;
81
82
0
  if (ctx->enc)
83
0
    ret = aesni_set_encrypt_key(key, keybits,
84
0
              ALIGN16(&ctx->block_key));
85
0
  else
86
0
    ret = aesni_set_decrypt_key(key, keybits,
87
0
              ALIGN16(&ctx->block_key));
88
89
0
  if (ret != 0)
90
0
    return gnutls_assert_val(GNUTLS_E_ENCRYPTION_FAILED);
91
92
0
  ret = aesni_set_encrypt_key(key + (keysize / 2), keybits,
93
0
            ALIGN16(&ctx->tweak_key));
94
0
  if (ret != 0)
95
0
    return gnutls_assert_val(GNUTLS_E_ENCRYPTION_FAILED);
96
97
0
  return 0;
98
0
}
99
100
static int x86_aes_xts_setiv(void *_ctx, const void *iv, size_t iv_size)
101
0
{
102
0
  struct x86_aes_xts_ctx *ctx = _ctx;
103
104
0
  if (iv_size != 16)
105
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
106
107
0
  memcpy(ctx->iv, iv, 16);
108
0
  return 0;
109
0
}
110
111
static int x86_aes_xts_encrypt(void *_ctx, const void *src, size_t src_size,
112
             void *dst, size_t dst_size)
113
0
{
114
0
  struct x86_aes_xts_ctx *ctx = _ctx;
115
116
0
  if (unlikely(dst_size < src_size))
117
0
    return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
118
119
0
  if (src_size < 16)
120
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
121
122
0
  aesni_xts_encrypt(src, dst, src_size, ALIGN16(&ctx->block_key),
123
0
        ALIGN16(&ctx->tweak_key), ctx->iv);
124
0
  return 0;
125
0
}
126
127
static int x86_aes_xts_decrypt(void *_ctx, const void *src, size_t src_size,
128
             void *dst, size_t dst_size)
129
0
{
130
0
  struct x86_aes_xts_ctx *ctx = _ctx;
131
132
0
  if (unlikely(dst_size < src_size))
133
0
    return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
134
135
0
  if (src_size < 16)
136
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
137
138
0
  aesni_xts_decrypt(src, dst, src_size, ALIGN16(&ctx->block_key),
139
0
        ALIGN16(&ctx->tweak_key), ctx->iv);
140
0
  return 0;
141
0
}
142
143
static void x86_aes_xts_deinit(void *_ctx)
144
0
{
145
0
  struct x86_aes_xts_ctx *ctx = _ctx;
146
147
0
  zeroize_temp_key(ctx, sizeof(*ctx));
148
0
  gnutls_free(ctx);
149
0
}
150
151
const gnutls_crypto_cipher_st _gnutls_aes_xts_x86_aesni = {
152
  .init = x86_aes_xts_cipher_init,
153
  .setkey = x86_aes_xts_cipher_setkey,
154
  .setiv = x86_aes_xts_setiv,
155
  .encrypt = x86_aes_xts_encrypt,
156
  .decrypt = x86_aes_xts_decrypt,
157
  .deinit = x86_aes_xts_deinit,
158
};