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> 23typedef __u64 u64; 24typedef __u32 u32; 25typedef __u8 u8; 26typedef __s64 s64; 27#else 28typedef uint64_t u64, __le64; 29typedef uint32_t u32, __le32; 30typedef uint8_t u8; 31typedef 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 58static __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} 64static __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} 70static __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 76static 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 88void 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 95void 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