xref: /dflybsd-src/crypto/libressl/apps/openssl/rand.c (revision cca6fc5243d2098262ea81f83ad5b28d3b800f4a)
1*cca6fc52SDaniel Fojt /* $OpenBSD: rand.c,v 1.14 2019/07/14 03:30:46 guenther Exp $ */
2f5b1c8a1SJohn Marino /* ====================================================================
3f5b1c8a1SJohn Marino  * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
4f5b1c8a1SJohn Marino  *
5f5b1c8a1SJohn Marino  * Redistribution and use in source and binary forms, with or without
6f5b1c8a1SJohn Marino  * modification, are permitted provided that the following conditions
7f5b1c8a1SJohn Marino  * are met:
8f5b1c8a1SJohn Marino  *
9f5b1c8a1SJohn Marino  * 1. Redistributions of source code must retain the above copyright
10f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer.
11f5b1c8a1SJohn Marino  *
12f5b1c8a1SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
13f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer in
14f5b1c8a1SJohn Marino  *    the documentation and/or other materials provided with the
15f5b1c8a1SJohn Marino  *    distribution.
16f5b1c8a1SJohn Marino  *
17f5b1c8a1SJohn Marino  * 3. All advertising materials mentioning features or use of this
18f5b1c8a1SJohn Marino  *    software must display the following acknowledgment:
19f5b1c8a1SJohn Marino  *    "This product includes software developed by the OpenSSL Project
20f5b1c8a1SJohn Marino  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
21f5b1c8a1SJohn Marino  *
22f5b1c8a1SJohn Marino  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23f5b1c8a1SJohn Marino  *    endorse or promote products derived from this software without
24f5b1c8a1SJohn Marino  *    prior written permission. For written permission, please contact
25f5b1c8a1SJohn Marino  *    openssl-core@openssl.org.
26f5b1c8a1SJohn Marino  *
27f5b1c8a1SJohn Marino  * 5. Products derived from this software may not be called "OpenSSL"
28f5b1c8a1SJohn Marino  *    nor may "OpenSSL" appear in their names without prior written
29f5b1c8a1SJohn Marino  *    permission of the OpenSSL Project.
30f5b1c8a1SJohn Marino  *
31f5b1c8a1SJohn Marino  * 6. Redistributions of any form whatsoever must retain the following
32f5b1c8a1SJohn Marino  *    acknowledgment:
33f5b1c8a1SJohn Marino  *    "This product includes software developed by the OpenSSL Project
34f5b1c8a1SJohn Marino  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
35f5b1c8a1SJohn Marino  *
36f5b1c8a1SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37f5b1c8a1SJohn Marino  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38f5b1c8a1SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39f5b1c8a1SJohn Marino  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
40f5b1c8a1SJohn Marino  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41f5b1c8a1SJohn Marino  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42f5b1c8a1SJohn Marino  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43f5b1c8a1SJohn Marino  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44f5b1c8a1SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45f5b1c8a1SJohn Marino  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46f5b1c8a1SJohn Marino  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47f5b1c8a1SJohn Marino  * OF THE POSSIBILITY OF SUCH DAMAGE.
48f5b1c8a1SJohn Marino  * ====================================================================
49f5b1c8a1SJohn Marino  *
50f5b1c8a1SJohn Marino  * This product includes cryptographic software written by Eric Young
51f5b1c8a1SJohn Marino  * (eay@cryptsoft.com).  This product includes software written by Tim
52f5b1c8a1SJohn Marino  * Hudson (tjh@cryptsoft.com).
53f5b1c8a1SJohn Marino  *
54f5b1c8a1SJohn Marino  */
55f5b1c8a1SJohn Marino 
56f5b1c8a1SJohn Marino #include <ctype.h>
57f5b1c8a1SJohn Marino #include <stdio.h>
58f5b1c8a1SJohn Marino #include <string.h>
59f5b1c8a1SJohn Marino 
60f5b1c8a1SJohn Marino #include "apps.h"
61f5b1c8a1SJohn Marino 
62f5b1c8a1SJohn Marino #include <openssl/bio.h>
63f5b1c8a1SJohn Marino #include <openssl/err.h>
64f5b1c8a1SJohn Marino 
65f5b1c8a1SJohn Marino struct {
66f5b1c8a1SJohn Marino 	int base64;
67f5b1c8a1SJohn Marino 	int hex;
68f5b1c8a1SJohn Marino 	char *outfile;
69f5b1c8a1SJohn Marino } rand_config;
70f5b1c8a1SJohn Marino 
71*cca6fc52SDaniel Fojt static const struct option rand_options[] = {
72f5b1c8a1SJohn Marino 	{
73f5b1c8a1SJohn Marino 		.name = "base64",
74f5b1c8a1SJohn Marino 		.desc = "Perform base64 encoding on output",
75f5b1c8a1SJohn Marino 		.type = OPTION_FLAG,
76f5b1c8a1SJohn Marino 		.opt.flag = &rand_config.base64,
77f5b1c8a1SJohn Marino 	},
78f5b1c8a1SJohn Marino 	{
79f5b1c8a1SJohn Marino 		.name = "hex",
80f5b1c8a1SJohn Marino 		.desc = "Hexadecimal output",
81f5b1c8a1SJohn Marino 		.type = OPTION_FLAG,
82f5b1c8a1SJohn Marino 		.opt.flag = &rand_config.hex,
83f5b1c8a1SJohn Marino 	},
84f5b1c8a1SJohn Marino 	{
85f5b1c8a1SJohn Marino 		.name = "out",
86f5b1c8a1SJohn Marino 		.argname = "file",
87f5b1c8a1SJohn Marino 		.desc = "Write to the given file instead of standard output",
88f5b1c8a1SJohn Marino 		.type = OPTION_ARG,
89f5b1c8a1SJohn Marino 		.opt.arg = &rand_config.outfile,
90f5b1c8a1SJohn Marino 	},
91f5b1c8a1SJohn Marino 	{NULL},
92f5b1c8a1SJohn Marino };
93f5b1c8a1SJohn Marino 
94f5b1c8a1SJohn Marino static void
rand_usage()95f5b1c8a1SJohn Marino rand_usage()
96f5b1c8a1SJohn Marino {
97f5b1c8a1SJohn Marino 	fprintf(stderr,
98f5b1c8a1SJohn Marino 	    "usage: rand [-base64 | -hex] [-out file] num\n");
99f5b1c8a1SJohn Marino 	options_usage(rand_options);
100f5b1c8a1SJohn Marino }
101f5b1c8a1SJohn Marino 
102f5b1c8a1SJohn Marino int
rand_main(int argc,char ** argv)103f5b1c8a1SJohn Marino rand_main(int argc, char **argv)
104f5b1c8a1SJohn Marino {
105f5b1c8a1SJohn Marino 	char *num_bytes = NULL;
106f5b1c8a1SJohn Marino 	int ret = 1;
107f5b1c8a1SJohn Marino 	int badopt = 0;
108f5b1c8a1SJohn Marino 	int num = -1;
109f5b1c8a1SJohn Marino 	int i, r;
110f5b1c8a1SJohn Marino 	BIO *out = NULL;
111f5b1c8a1SJohn Marino 
112f5b1c8a1SJohn Marino 	if (single_execution) {
11372c33676SMaxim Ag 		if (pledge("stdio cpath wpath rpath", NULL) == -1) {
114f5b1c8a1SJohn Marino 			perror("pledge");
115f5b1c8a1SJohn Marino 			exit(1);
116f5b1c8a1SJohn Marino 		}
117f5b1c8a1SJohn Marino 	}
118f5b1c8a1SJohn Marino 
119f5b1c8a1SJohn Marino 	memset(&rand_config, 0, sizeof(rand_config));
120f5b1c8a1SJohn Marino 
121f5b1c8a1SJohn Marino 	if (options_parse(argc, argv, rand_options, &num_bytes, NULL) != 0) {
122f5b1c8a1SJohn Marino 		rand_usage();
123f5b1c8a1SJohn Marino 		return (1);
124f5b1c8a1SJohn Marino 	}
125f5b1c8a1SJohn Marino 
126f5b1c8a1SJohn Marino 	if (num_bytes != NULL) {
127f5b1c8a1SJohn Marino 		r = sscanf(num_bytes, "%d", &num);
128f5b1c8a1SJohn Marino 		if (r == 0 || num < 0)
129f5b1c8a1SJohn Marino 			badopt = 1;
130f5b1c8a1SJohn Marino 	} else
131f5b1c8a1SJohn Marino 		badopt = 1;
132f5b1c8a1SJohn Marino 
133f5b1c8a1SJohn Marino 	if (rand_config.hex && rand_config.base64)
134f5b1c8a1SJohn Marino 		badopt = 1;
135f5b1c8a1SJohn Marino 
136f5b1c8a1SJohn Marino 	if (badopt) {
137f5b1c8a1SJohn Marino 		rand_usage();
138f5b1c8a1SJohn Marino 		goto err;
139f5b1c8a1SJohn Marino 	}
140f5b1c8a1SJohn Marino 
141f5b1c8a1SJohn Marino 	out = BIO_new(BIO_s_file());
142f5b1c8a1SJohn Marino 	if (out == NULL)
143f5b1c8a1SJohn Marino 		goto err;
144f5b1c8a1SJohn Marino 	if (rand_config.outfile != NULL)
145f5b1c8a1SJohn Marino 		r = BIO_write_filename(out, rand_config.outfile);
146f5b1c8a1SJohn Marino 	else
147f5b1c8a1SJohn Marino 		r = BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
148f5b1c8a1SJohn Marino 	if (r <= 0)
149f5b1c8a1SJohn Marino 		goto err;
150f5b1c8a1SJohn Marino 	if (rand_config.base64) {
151f5b1c8a1SJohn Marino 		BIO *b64 = BIO_new(BIO_f_base64());
152f5b1c8a1SJohn Marino 		if (b64 == NULL)
153f5b1c8a1SJohn Marino 			goto err;
154f5b1c8a1SJohn Marino 		out = BIO_push(b64, out);
155f5b1c8a1SJohn Marino 	}
156f5b1c8a1SJohn Marino 
157f5b1c8a1SJohn Marino 	while (num > 0) {
158f5b1c8a1SJohn Marino 		unsigned char buf[4096];
159f5b1c8a1SJohn Marino 		int chunk;
160f5b1c8a1SJohn Marino 
161f5b1c8a1SJohn Marino 		chunk = num;
162f5b1c8a1SJohn Marino 		if (chunk > (int) sizeof(buf))
163f5b1c8a1SJohn Marino 			chunk = sizeof(buf);
164f5b1c8a1SJohn Marino 		arc4random_buf(buf, chunk);
165f5b1c8a1SJohn Marino 		if (rand_config.hex) {
166f5b1c8a1SJohn Marino 			for (i = 0; i < chunk; i++)
167f5b1c8a1SJohn Marino 				BIO_printf(out, "%02x", buf[i]);
168f5b1c8a1SJohn Marino 		} else
169f5b1c8a1SJohn Marino 			BIO_write(out, buf, chunk);
170f5b1c8a1SJohn Marino 		num -= chunk;
171f5b1c8a1SJohn Marino 	}
172f5b1c8a1SJohn Marino 
173f5b1c8a1SJohn Marino 	if (rand_config.hex)
174f5b1c8a1SJohn Marino 		BIO_puts(out, "\n");
175f5b1c8a1SJohn Marino 	(void) BIO_flush(out);
176f5b1c8a1SJohn Marino 
177f5b1c8a1SJohn Marino 	ret = 0;
178f5b1c8a1SJohn Marino 
179f5b1c8a1SJohn Marino  err:
180f5b1c8a1SJohn Marino 	ERR_print_errors(bio_err);
181f5b1c8a1SJohn Marino 	BIO_free_all(out);
182f5b1c8a1SJohn Marino 
183f5b1c8a1SJohn Marino 	return (ret);
184f5b1c8a1SJohn Marino }
185