1*adf37648SKyle Evans // SPDX-License-Identifier: GPL-2.0 OR MIT
2*adf37648SKyle Evans /*
3*adf37648SKyle Evans  * Copyright (C) 2018-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
4*adf37648SKyle Evans  */
5*adf37648SKyle Evans 
6*adf37648SKyle Evans #include "curve25519.h"
7*adf37648SKyle Evans 
8*adf37648SKyle Evans #include <stdint.h>
9*adf37648SKyle Evans #include <string.h>
10*adf37648SKyle Evans 
11*adf37648SKyle Evans #ifndef __BYTE_ORDER__
12*adf37648SKyle Evans #include <sys/param.h>
13*adf37648SKyle Evans #if !defined(BYTE_ORDER) || !defined(BIG_ENDIAN) || !defined(LITTLE_ENDIAN)
14*adf37648SKyle Evans #error "Unable to determine endianness."
15*adf37648SKyle Evans #endif
16*adf37648SKyle Evans #define __BYTE_ORDER__ BYTE_ORDER
17*adf37648SKyle Evans #define __ORDER_BIG_ENDIAN__ BIG_ENDIAN
18*adf37648SKyle Evans #define __ORDER_LITTLE_ENDIAN__ LITTLE_ENDIAN
19*adf37648SKyle Evans #endif
20*adf37648SKyle Evans 
21*adf37648SKyle Evans #ifdef __linux__
22*adf37648SKyle Evans #include <linux/types.h>
23*adf37648SKyle Evans typedef __u64 u64;
24*adf37648SKyle Evans typedef __u32 u32;
25*adf37648SKyle Evans typedef __u8 u8;
26*adf37648SKyle Evans typedef __s64 s64;
27*adf37648SKyle Evans #else
28*adf37648SKyle Evans typedef uint64_t u64, __le64;
29*adf37648SKyle Evans typedef uint32_t u32, __le32;
30*adf37648SKyle Evans typedef uint8_t u8;
31*adf37648SKyle Evans typedef int64_t s64;
32*adf37648SKyle Evans #endif
33*adf37648SKyle Evans #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
34*adf37648SKyle Evans #define le64_to_cpup(a) __builtin_bswap64(*(a))
35*adf37648SKyle Evans #define le32_to_cpup(a) __builtin_bswap32(*(a))
36*adf37648SKyle Evans #define cpu_to_le64(a) __builtin_bswap64(a)
37*adf37648SKyle Evans #else
38*adf37648SKyle Evans #define le64_to_cpup(a) (*(a))
39*adf37648SKyle Evans #define le32_to_cpup(a) (*(a))
40*adf37648SKyle Evans #define cpu_to_le64(a) (a)
41*adf37648SKyle Evans #endif
42*adf37648SKyle Evans #ifndef __unused
43*adf37648SKyle Evans #define __unused  __attribute__((unused))
44*adf37648SKyle Evans #endif
45*adf37648SKyle Evans #ifndef __always_inline
46*adf37648SKyle Evans #define __always_inline __inline __attribute__((__always_inline__))
47*adf37648SKyle Evans #endif
48*adf37648SKyle Evans #ifndef noinline
49*adf37648SKyle Evans #define noinline __attribute__((noinline))
50*adf37648SKyle Evans #endif
51*adf37648SKyle Evans #ifndef __aligned
52*adf37648SKyle Evans #define __aligned(x) __attribute__((aligned(x)))
53*adf37648SKyle Evans #endif
54*adf37648SKyle Evans #ifndef __force
55*adf37648SKyle Evans #define __force
56*adf37648SKyle Evans #endif
57*adf37648SKyle Evans 
get_unaligned_le32(const u8 * a)58*adf37648SKyle Evans static __always_inline __unused __le32 get_unaligned_le32(const u8 *a)
59*adf37648SKyle Evans {
60*adf37648SKyle Evans 	__le32 l;
61*adf37648SKyle Evans 	__builtin_memcpy(&l, a, sizeof(l));
62*adf37648SKyle Evans 	return le32_to_cpup(&l);
63*adf37648SKyle Evans }
get_unaligned_le64(const u8 * a)64*adf37648SKyle Evans static __always_inline __unused __le64 get_unaligned_le64(const u8 *a)
65*adf37648SKyle Evans {
66*adf37648SKyle Evans 	__le64 l;
67*adf37648SKyle Evans 	__builtin_memcpy(&l, a, sizeof(l));
68*adf37648SKyle Evans 	return le64_to_cpup(&l);
69*adf37648SKyle Evans }
put_unaligned_le64(u64 s,u8 * d)70*adf37648SKyle Evans static __always_inline __unused void put_unaligned_le64(u64 s, u8 *d)
71*adf37648SKyle Evans {
72*adf37648SKyle Evans 	__le64 l = cpu_to_le64(s);
73*adf37648SKyle Evans 	__builtin_memcpy(d, &l, sizeof(l));
74*adf37648SKyle Evans }
75*adf37648SKyle Evans 
memzero_explicit(void * s,size_t count)76*adf37648SKyle Evans static noinline void memzero_explicit(void *s, size_t count)
77*adf37648SKyle Evans {
78*adf37648SKyle Evans 	memset(s, 0, count);
79*adf37648SKyle Evans 	asm volatile("": :"r"(s) : "memory");
80*adf37648SKyle Evans }
81*adf37648SKyle Evans 
82*adf37648SKyle Evans #ifdef __SIZEOF_INT128__
83*adf37648SKyle Evans #include "curve25519-hacl64.h"
84*adf37648SKyle Evans #else
85*adf37648SKyle Evans #include "curve25519-fiat32.h"
86*adf37648SKyle Evans #endif
87*adf37648SKyle Evans 
curve25519_generate_public(uint8_t pub[static CURVE25519_KEY_SIZE],const uint8_t secret[static CURVE25519_KEY_SIZE])88*adf37648SKyle Evans void curve25519_generate_public(uint8_t pub[static CURVE25519_KEY_SIZE], const uint8_t secret[static CURVE25519_KEY_SIZE])
89*adf37648SKyle Evans {
90*adf37648SKyle Evans 	static const uint8_t basepoint[CURVE25519_KEY_SIZE] __aligned(sizeof(uintptr_t)) = { 9 };
91*adf37648SKyle Evans 
92*adf37648SKyle Evans 	curve25519(pub, secret, basepoint);
93*adf37648SKyle Evans }
94*adf37648SKyle Evans 
curve25519(uint8_t mypublic[static CURVE25519_KEY_SIZE],const uint8_t secret[static CURVE25519_KEY_SIZE],const uint8_t basepoint[static CURVE25519_KEY_SIZE])95*adf37648SKyle Evans void curve25519(uint8_t mypublic[static CURVE25519_KEY_SIZE], const uint8_t secret[static CURVE25519_KEY_SIZE], const uint8_t basepoint[static CURVE25519_KEY_SIZE])
96*adf37648SKyle Evans {
97*adf37648SKyle Evans 	curve25519_generic(mypublic, secret, basepoint);
98*adf37648SKyle Evans }
99