1 /*
2 * Copyright (C) 2017 - This file is part of libecc project
3 *
4 * Authors:
5 * Ryad BENADJILA <ryadbenadjila@gmail.com>
6 * Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr>
7 * Jean-Pierre FLORI <jean-pierre.flori@ssi.gouv.fr>
8 *
9 * Contributors:
10 * Nicolas VIVET <nicolas.vivet@ssi.gouv.fr>
11 * Karim KHALFALLAH <karim.khalfallah@ssi.gouv.fr>
12 *
13 * This software is licensed under a dual BSD and GPL v2 license.
14 * See LICENSE file at the root folder of the project.
15 */
16 #include <libecc/external_deps/rand.h>
17
18 /* Unix and compatible case (including macOS) */
19 #if defined(WITH_STDLIB) && (defined(__unix__) || defined(__APPLE__))
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <limits.h>
24
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28 #include <unistd.h>
29 #include <libecc/words/words.h>
30
31 /*
32 * Copy file content to buffer. Return 0 on success, i.e. if the request
33 * size has been read and copied to buffer and -1 otherwise.
34 */
fimport(unsigned char * buf,u16 buflen,const char * path)35 ATTRIBUTE_WARN_UNUSED_RET static int fimport(unsigned char *buf, u16 buflen,
36 const char *path)
37 {
38 u16 rem = buflen, copied = 0;
39 ssize_t ret;
40 int fd;
41
42 if ((buf == NULL) || (path == NULL)) {
43 ret = -1;
44 goto err;
45 }
46
47 fd = open(path, O_RDONLY);
48 if (fd == -1) {
49 printf("Unable to open input file %s\n", path);
50 ret = -1;
51 goto err;
52 }
53
54 while (rem) {
55 ret = (int)read(fd, buf + copied, rem);
56 if (ret <= 0) {
57 break;
58 } else {
59 rem = (u16)(rem - ret);
60 copied = (u16)(copied + ret);
61 }
62 }
63
64 if (close(fd)) {
65 printf("Unable to close input file %s\n", path);
66 ret = -1;
67 goto err;
68 }
69
70 ret = (copied == buflen) ? 0 : -1;
71
72 err:
73 return (int)ret;
74 }
75
get_random(unsigned char * buf,u16 len)76 int get_random(unsigned char *buf, u16 len)
77 {
78 return fimport(buf, len, "/dev/urandom");
79 }
80
81 /* Windows case */
82 #elif defined(WITH_STDLIB) && defined(__WIN32__)
83 #include <windows.h>
84 #include <wincrypt.h>
85
get_random(unsigned char * buf,u16 len)86 int get_random(unsigned char *buf, u16 len)
87 {
88 int ret;
89 HCRYPTPROV hCryptProv = 0;
90
91 if (CryptAcquireContext(&hCryptProv, NULL, NULL,
92 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) == FALSE) {
93 ret = -1;
94 goto err;
95 }
96
97 if (CryptGenRandom(hCryptProv, len, buf) == FALSE) {
98 CryptReleaseContext(hCryptProv, 0);
99 ret = -1;
100 goto err;
101 }
102 CryptReleaseContext(hCryptProv, 0);
103 ret = 0;
104
105 err:
106 return ret;
107 }
108
109 /* No platform detected, the user must provide an implementation! */
110 #else
111 /* WARNING: when providing/implementing the get_random function, one must:
112 * - Use a proper entropy source with a TRNG (True Random Number Generator)
113 * basis and clean PRNG (Pseudo-Random Number Generator) post-processing
114 * when needed.
115 * - Use a non-leaking generator in contexts where attackers that have access
116 * to side channels are a plausible threat (a process in an OS sharing memory
117 * and caches with other possibly malicious processes, a microcontroller
118 * that can be observed using EM probes or power consumtion, ...).
119 */
120 #error "rand.c: you have to implement get_random with a proper entropy source!"
121 #endif
122