xref: /aosp_15_r20/external/boringssl/src/tool/rand.cc (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1*8fb009dcSAndroid Build Coastguard Worker /* Copyright (c) 2015, Google Inc.
2*8fb009dcSAndroid Build Coastguard Worker  *
3*8fb009dcSAndroid Build Coastguard Worker  * Permission to use, copy, modify, and/or distribute this software for any
4*8fb009dcSAndroid Build Coastguard Worker  * purpose with or without fee is hereby granted, provided that the above
5*8fb009dcSAndroid Build Coastguard Worker  * copyright notice and this permission notice appear in all copies.
6*8fb009dcSAndroid Build Coastguard Worker  *
7*8fb009dcSAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8*8fb009dcSAndroid Build Coastguard Worker  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9*8fb009dcSAndroid Build Coastguard Worker  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10*8fb009dcSAndroid Build Coastguard Worker  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11*8fb009dcSAndroid Build Coastguard Worker  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12*8fb009dcSAndroid Build Coastguard Worker  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13*8fb009dcSAndroid Build Coastguard Worker  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14*8fb009dcSAndroid Build Coastguard Worker 
15*8fb009dcSAndroid Build Coastguard Worker #include <string>
16*8fb009dcSAndroid Build Coastguard Worker #include <vector>
17*8fb009dcSAndroid Build Coastguard Worker 
18*8fb009dcSAndroid Build Coastguard Worker #include <stdint.h>
19*8fb009dcSAndroid Build Coastguard Worker #include <stdio.h>
20*8fb009dcSAndroid Build Coastguard Worker #include <stdlib.h>
21*8fb009dcSAndroid Build Coastguard Worker 
22*8fb009dcSAndroid Build Coastguard Worker #include <openssl/rand.h>
23*8fb009dcSAndroid Build Coastguard Worker 
24*8fb009dcSAndroid Build Coastguard Worker #include "internal.h"
25*8fb009dcSAndroid Build Coastguard Worker 
26*8fb009dcSAndroid Build Coastguard Worker 
27*8fb009dcSAndroid Build Coastguard Worker static const struct argument kArguments[] = {
28*8fb009dcSAndroid Build Coastguard Worker     {
29*8fb009dcSAndroid Build Coastguard Worker      "-hex", kBooleanArgument,
30*8fb009dcSAndroid Build Coastguard Worker      "Hex encoded output."
31*8fb009dcSAndroid Build Coastguard Worker     },
32*8fb009dcSAndroid Build Coastguard Worker     {
33*8fb009dcSAndroid Build Coastguard Worker      "", kOptionalArgument, "",
34*8fb009dcSAndroid Build Coastguard Worker     },
35*8fb009dcSAndroid Build Coastguard Worker };
36*8fb009dcSAndroid Build Coastguard Worker 
Rand(const std::vector<std::string> & args)37*8fb009dcSAndroid Build Coastguard Worker bool Rand(const std::vector<std::string> &args) {
38*8fb009dcSAndroid Build Coastguard Worker   bool forever = true, hex = false;
39*8fb009dcSAndroid Build Coastguard Worker   size_t len = 0;
40*8fb009dcSAndroid Build Coastguard Worker 
41*8fb009dcSAndroid Build Coastguard Worker   if (!args.empty()) {
42*8fb009dcSAndroid Build Coastguard Worker     std::vector<std::string> args_copy(args);
43*8fb009dcSAndroid Build Coastguard Worker     const std::string &last_arg = args.back();
44*8fb009dcSAndroid Build Coastguard Worker 
45*8fb009dcSAndroid Build Coastguard Worker     if (!last_arg.empty() && last_arg[0] != '-') {
46*8fb009dcSAndroid Build Coastguard Worker       char *endptr;
47*8fb009dcSAndroid Build Coastguard Worker       unsigned long long num = strtoull(last_arg.c_str(), &endptr, 10);
48*8fb009dcSAndroid Build Coastguard Worker       if (*endptr == 0) {
49*8fb009dcSAndroid Build Coastguard Worker         len = num;
50*8fb009dcSAndroid Build Coastguard Worker         forever = false;
51*8fb009dcSAndroid Build Coastguard Worker         args_copy.pop_back();
52*8fb009dcSAndroid Build Coastguard Worker       }
53*8fb009dcSAndroid Build Coastguard Worker     }
54*8fb009dcSAndroid Build Coastguard Worker 
55*8fb009dcSAndroid Build Coastguard Worker     std::map<std::string, std::string> args_map;
56*8fb009dcSAndroid Build Coastguard Worker     if (!ParseKeyValueArguments(&args_map, args_copy, kArguments)) {
57*8fb009dcSAndroid Build Coastguard Worker       PrintUsage(kArguments);
58*8fb009dcSAndroid Build Coastguard Worker       return false;
59*8fb009dcSAndroid Build Coastguard Worker     }
60*8fb009dcSAndroid Build Coastguard Worker 
61*8fb009dcSAndroid Build Coastguard Worker     hex = args_map.count("-hex") > 0;
62*8fb009dcSAndroid Build Coastguard Worker   }
63*8fb009dcSAndroid Build Coastguard Worker 
64*8fb009dcSAndroid Build Coastguard Worker   uint8_t buf[4096];
65*8fb009dcSAndroid Build Coastguard Worker   uint8_t hex_buf[8192];
66*8fb009dcSAndroid Build Coastguard Worker 
67*8fb009dcSAndroid Build Coastguard Worker   size_t done = 0;
68*8fb009dcSAndroid Build Coastguard Worker   while (forever || done < len) {
69*8fb009dcSAndroid Build Coastguard Worker     size_t todo = sizeof(buf);
70*8fb009dcSAndroid Build Coastguard Worker     if (!forever && todo > len - done) {
71*8fb009dcSAndroid Build Coastguard Worker       todo = len - done;
72*8fb009dcSAndroid Build Coastguard Worker     }
73*8fb009dcSAndroid Build Coastguard Worker     RAND_bytes(buf, todo);
74*8fb009dcSAndroid Build Coastguard Worker     if (hex) {
75*8fb009dcSAndroid Build Coastguard Worker       static const char hextable[16 + 1] = "0123456789abcdef";
76*8fb009dcSAndroid Build Coastguard Worker       for (unsigned i = 0; i < todo; i++) {
77*8fb009dcSAndroid Build Coastguard Worker         hex_buf[i*2] = hextable[buf[i] >> 4];
78*8fb009dcSAndroid Build Coastguard Worker         hex_buf[i*2 + 1] = hextable[buf[i] & 0xf];
79*8fb009dcSAndroid Build Coastguard Worker       }
80*8fb009dcSAndroid Build Coastguard Worker       if (fwrite(hex_buf, todo*2, 1, stdout) != 1) {
81*8fb009dcSAndroid Build Coastguard Worker         return false;
82*8fb009dcSAndroid Build Coastguard Worker       }
83*8fb009dcSAndroid Build Coastguard Worker     } else {
84*8fb009dcSAndroid Build Coastguard Worker       if (fwrite(buf, todo, 1, stdout) != 1) {
85*8fb009dcSAndroid Build Coastguard Worker         return false;
86*8fb009dcSAndroid Build Coastguard Worker       }
87*8fb009dcSAndroid Build Coastguard Worker     }
88*8fb009dcSAndroid Build Coastguard Worker     done += todo;
89*8fb009dcSAndroid Build Coastguard Worker   }
90*8fb009dcSAndroid Build Coastguard Worker 
91*8fb009dcSAndroid Build Coastguard Worker   if (hex && fwrite("\n", 1, 1, stdout) != 1) {
92*8fb009dcSAndroid Build Coastguard Worker     return false;
93*8fb009dcSAndroid Build Coastguard Worker   }
94*8fb009dcSAndroid Build Coastguard Worker 
95*8fb009dcSAndroid Build Coastguard Worker   return true;
96*8fb009dcSAndroid Build Coastguard Worker }
97