1 // Copyright 2016 The Fuchsia Authors
2 // Copyright (c) 2016, Google, Inc. All rights reserved
3 //
4 // Use of this source code is governed by a MIT-style
5 // license that can be found in the LICENSE file or at
6 // https://opensource.org/licenses/MIT
7 
8 #include <dev/hw_rng.h>
9 
10 #include <debug.h>
11 #include <fbl/algorithm.h>
12 #include <lib/console.h>
13 #include <stdlib.h>
14 
cmd_rng32(int argc,const cmd_args * argv,uint32_t flags)15 static int cmd_rng32(int argc, const cmd_args* argv, uint32_t flags) {
16     uint32_t val = hw_rng_get_u32();
17     printf("Random val = %u (0x%08x)\n", val, val);
18     return ZX_OK;
19 }
20 
cmd_rng(int argc,const cmd_args * argv,uint32_t flags)21 static int cmd_rng(int argc, const cmd_args* argv, uint32_t flags) {
22     if ((argc < 2) || (argc > 3)) {
23         printf("Invalid argument count\n\n"
24                "Usage : %s <N> [wait]\n"
25                "N     : Number of bytes to generate.\n"
26                "wait  : true  -> wait indefinitely for bytes to be generated\n"
27                "      : false -> terminate if HW generator runs out of entropy (default)\n",
28                argv[0].str);
29         return ZX_ERR_INVALID_ARGS;
30     }
31 
32     printf("Generating %lu random bytes\n", argv[1].u);
33 
34     size_t offset = 0;
35     bool wait = (argc == 3) ? argv[2].b : false;
36     while (offset < argv[1].u) {
37         uint8_t bytes[16];
38         size_t todo, done;
39 
40         todo = fbl::min(sizeof(bytes), argv[1].u - offset);
41         done = hw_rng_get_entropy(bytes, todo, wait);
42         DEBUG_ASSERT(done <= todo);
43 
44         hexdump8_ex(bytes, done, offset);
45         offset += done;
46 
47         if (done < todo) {
48             printf("Entropy exhausted after %zu byte%s\n",
49                    offset, offset == 1 ? "" : "s");
50             break;
51         }
52     }
53 
54     return ZX_OK;
55 }
56 
57 STATIC_COMMAND_START
58 STATIC_COMMAND("rng32",
59                "Generate and print a random 32 bit unsigned integer using the HW RNG",
60                &cmd_rng32)
61 STATIC_COMMAND("rng",
62                "Generate and print N random bytes using the HW RNG",
63                &cmd_rng)
64 STATIC_COMMAND_END(hw_rng);
65