3 Copyright (C) 2015 Niels Möller
5 This file is part of GNU Nettle.
7 GNU Nettle is free software: you can redistribute it and/or
8 modify it under the terms of either:
10 * the GNU Lesser General Public License as published by the Free
11 Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
16 * the GNU General Public License as published by the Free
17 Software Foundation; either version 2 of the License, or (at your
18 option) any later version.
20 or both in parallel, as here.
22 GNU Nettle is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 General Public License for more details.
27 You should have received copies of the GNU General Public License and
28 the GNU Lesser General Public License along with this program. If
29 not, see http://www.gnu.org/licenses/.
41 #include "nettle-types.h"
43 #include "aes-internal.h"
44 #include "fat-setup.h"
48 /* /proc/cpuinfo "CPU Architecture" doesn't correspond exactly to
49 ARM architecture version, but it's good enough for our purposes.
50 Will be set to 5, 6, 7 or 8. */
51 unsigned arch_version;
55 #define SKIP(s, slen, literal, llen) \
56 (((slen) >= (llen) && memcmp ((s), (literal), llen) == 0) \
57 ? ((slen) -= (llen), (s) += (llen), 1) : 0)
58 #define MATCH(s, slen, literal, llen) \
59 ((slen) == (llen) && memcmp ((s), (literal), llen) == 0)
62 get_arm_features (struct arm_features *features)
65 features->arch_version = 5;
66 features->have_neon = 0;
68 s = secure_getenv (ENV_OVERRIDE);
72 const char *sep = strchr (s, ',');
73 size_t length = sep ? (size_t) (sep - s) : strlen(s);
75 if (SKIP (s, length, "arch:", 5))
77 if (length == 1 && *s >= '0' && *s <= '9')
78 features->arch_version = *s - '0';
80 else if (MATCH (s, length, "neon", 4))
81 features->have_neon = 1;
91 int seen_features = 0;
93 f = fopen ("/proc/cpuinfo", "r");
96 while (seen_features + seen_arch < 2
97 && fgets (line, sizeof(line), f))
101 sep = strchr (line, ':');
104 for (p = sep; p - line > 0 && p[-1] == '\t'; p--)
110 if (strcmp (line, "Features") == 0)
112 features->have_neon = (strstr (p, " neon ") != NULL);
115 else if (strcmp (line, "CPU architecture") == 0)
117 /* Don't use strtol, since it's locale dependent. */
120 if (p[0] > '5' && p[0] <= '9')
121 features->arch_version = p[0] - '0';
122 else if (strcmp (p, "AArch64") == 0)
123 features->arch_version = 8;
127 if (features->arch_version >= 8)
129 /* Neon is not required, and maybe not listed in feature flags */
130 features->have_neon = 1;
136 DECLARE_FAT_FUNC(_nettle_aes_encrypt, aes_crypt_internal_func)
137 DECLARE_FAT_FUNC_VAR(aes_encrypt, aes_crypt_internal_func, arm)
138 DECLARE_FAT_FUNC_VAR(aes_encrypt, aes_crypt_internal_func, armv6)
140 DECLARE_FAT_FUNC(_nettle_aes_decrypt, aes_crypt_internal_func)
141 DECLARE_FAT_FUNC_VAR(aes_decrypt, aes_crypt_internal_func, arm)
142 DECLARE_FAT_FUNC_VAR(aes_decrypt, aes_crypt_internal_func, armv6)
144 DECLARE_FAT_FUNC(_nettle_salsa20_core, salsa20_core_func)
145 DECLARE_FAT_FUNC_VAR(salsa20_core, salsa20_core_func, c)
146 DECLARE_FAT_FUNC_VAR(salsa20_core, salsa20_core_func, neon)
148 DECLARE_FAT_FUNC(_nettle_sha1_compress, sha1_compress_func)
149 DECLARE_FAT_FUNC_VAR(sha1_compress, sha1_compress_func, c)
150 DECLARE_FAT_FUNC_VAR(sha1_compress, sha1_compress_func, armv6)
152 DECLARE_FAT_FUNC(_nettle_sha256_compress, sha256_compress_func)
153 DECLARE_FAT_FUNC_VAR(sha256_compress, sha256_compress_func, c)
154 DECLARE_FAT_FUNC_VAR(sha256_compress, sha256_compress_func, armv6)
156 DECLARE_FAT_FUNC(_nettle_sha512_compress, sha512_compress_func)
157 DECLARE_FAT_FUNC_VAR(sha512_compress, sha512_compress_func, c)
158 DECLARE_FAT_FUNC_VAR(sha512_compress, sha512_compress_func, neon)
160 DECLARE_FAT_FUNC(nettle_sha3_permute, sha3_permute_func)
161 DECLARE_FAT_FUNC_VAR(sha3_permute, sha3_permute_func, c)
162 DECLARE_FAT_FUNC_VAR(sha3_permute, sha3_permute_func, neon)
164 DECLARE_FAT_FUNC(_nettle_umac_nh, umac_nh_func)
165 DECLARE_FAT_FUNC_VAR(umac_nh, umac_nh_func, c);
166 DECLARE_FAT_FUNC_VAR(umac_nh, umac_nh_func, neon);
168 DECLARE_FAT_FUNC(_nettle_umac_nh_n, umac_nh_n_func)
169 DECLARE_FAT_FUNC_VAR(umac_nh_n, umac_nh_n_func, c);
170 DECLARE_FAT_FUNC_VAR(umac_nh_n, umac_nh_n_func, neon);
172 static void CONSTRUCTOR
175 struct arm_features features;
178 get_arm_features (&features);
180 verbose = getenv (ENV_VERBOSE) != NULL;
182 fprintf (stderr, "libnettle: cpu features: arch:%d%s\n",
183 features.arch_version,
184 features.have_neon ? ",neon" : "");
186 if (features.arch_version >= 6)
189 fprintf (stderr, "libnettle: enabling armv6 code.\n");
190 _nettle_aes_encrypt_vec = _nettle_aes_encrypt_armv6;
191 _nettle_aes_decrypt_vec = _nettle_aes_decrypt_armv6;
192 _nettle_sha1_compress_vec = _nettle_sha1_compress_armv6;
193 _nettle_sha256_compress_vec = _nettle_sha256_compress_armv6;
198 fprintf (stderr, "libnettle: not enabling armv6 code.\n");
199 _nettle_aes_encrypt_vec = _nettle_aes_encrypt_arm;
200 _nettle_aes_decrypt_vec = _nettle_aes_decrypt_arm;
201 _nettle_sha1_compress_vec = _nettle_sha1_compress_c;
202 _nettle_sha256_compress_vec = _nettle_sha256_compress_c;
204 if (features.have_neon)
207 fprintf (stderr, "libnettle: enabling neon code.\n");
208 _nettle_salsa20_core_vec = _nettle_salsa20_core_neon;
209 _nettle_sha512_compress_vec = _nettle_sha512_compress_neon;
210 nettle_sha3_permute_vec = _nettle_sha3_permute_neon;
211 _nettle_umac_nh_vec = _nettle_umac_nh_neon;
212 _nettle_umac_nh_n_vec = _nettle_umac_nh_n_neon;
217 fprintf (stderr, "libnettle: not enabling neon code.\n");
218 _nettle_salsa20_core_vec = _nettle_salsa20_core_c;
219 _nettle_sha512_compress_vec = _nettle_sha512_compress_c;
220 nettle_sha3_permute_vec = _nettle_sha3_permute_c;
221 _nettle_umac_nh_vec = _nettle_umac_nh_c;
222 _nettle_umac_nh_n_vec = _nettle_umac_nh_n_c;
226 DEFINE_FAT_FUNC(_nettle_aes_encrypt, void,
227 (unsigned rounds, const uint32_t *keys,
228 const struct aes_table *T,
229 size_t length, uint8_t *dst,
231 (rounds, keys, T, length, dst, src))
233 DEFINE_FAT_FUNC(_nettle_aes_decrypt, void,
234 (unsigned rounds, const uint32_t *keys,
235 const struct aes_table *T,
236 size_t length, uint8_t *dst,
238 (rounds, keys, T, length, dst, src))
240 DEFINE_FAT_FUNC(_nettle_salsa20_core, void,
241 (uint32_t *dst, const uint32_t *src, unsigned rounds),
244 DEFINE_FAT_FUNC(_nettle_sha1_compress, void,
245 (uint32_t *state, const uint8_t *input),
248 DEFINE_FAT_FUNC(_nettle_sha256_compress, void,
249 (uint32_t *state, const uint8_t *input, const uint32_t *k),
252 DEFINE_FAT_FUNC(_nettle_sha512_compress, void,
253 (uint64_t *state, const uint8_t *input, const uint64_t *k),
256 DEFINE_FAT_FUNC(nettle_sha3_permute, void,
257 (struct sha3_state *state), (state))
259 DEFINE_FAT_FUNC(_nettle_umac_nh, uint64_t,
260 (const uint32_t *key, unsigned length, const uint8_t *msg),
263 DEFINE_FAT_FUNC(_nettle_umac_nh_n, void,
264 (uint64_t *out, unsigned n, const uint32_t *key,
265 unsigned length, const uint8_t *msg),
266 (out, n, key, length, msg))