GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/openssl/rand.c Lines: 46 54 85.2 %
Date: 2017-11-07 Branches: 26 37 70.3 %

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