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