xref: /openbsd-src/lib/libssl/tls13_lib.c (revision 5e3c7963eb248119b7dfd4b0defad58a7d9cd306)
1 /*	$OpenBSD: tls13_lib.c,v 1.3 2019/01/21 13:45:57 jsing Exp $ */
2 /*
3  * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <limits.h>
19 #include <stddef.h>
20 
21 #include <openssl/evp.h>
22 
23 #include "ssl_locl.h"
24 #include "tls13_internal.h"
25 
26 const EVP_AEAD *
27 tls13_cipher_aead(const SSL_CIPHER *cipher)
28 {
29 	if (cipher == NULL)
30 		return NULL;
31 	if (cipher->algorithm_ssl != SSL_TLSV1_3)
32 		return NULL;
33 
34 	switch (cipher->algorithm_enc) {
35 	case SSL_AES128GCM:
36 		return EVP_aead_aes_128_gcm();
37 	case SSL_AES256GCM:
38 		return EVP_aead_aes_256_gcm();
39 	case SSL_CHACHA20POLY1305:
40 		return EVP_aead_chacha20_poly1305();
41 	}
42 
43 	return NULL;
44 }
45 
46 const EVP_MD *
47 tls13_cipher_hash(const SSL_CIPHER *cipher)
48 {
49 	if (cipher == NULL)
50 		return NULL;
51 	if (cipher->algorithm_ssl != SSL_TLSV1_3)
52 		return NULL;
53 
54 	switch (cipher->algorithm2) {
55 	case SSL_HANDSHAKE_MAC_SHA256:
56 		return EVP_sha256();
57 	case SSL_HANDSHAKE_MAC_SHA384:
58 		return EVP_sha384();
59 	}
60 
61 	return NULL;
62 }
63 
64 struct tls13_ctx *
65 tls13_ctx_new(int mode)
66 {
67 	struct tls13_ctx *ctx = NULL;
68 
69 	if ((ctx = calloc(sizeof(struct tls13_ctx), 1)) == NULL)
70 		goto err;
71 
72 	ctx->mode = mode;
73 
74 	if ((ctx->rl = tls13_record_layer_new(tls13_legacy_wire_read_cb,
75 	    tls13_legacy_wire_write_cb, NULL, NULL, ctx)) == NULL)
76 		goto err;
77 
78 	return ctx;
79 
80  err:
81 	tls13_ctx_free(ctx);
82 
83 	return NULL;
84 }
85 
86 void
87 tls13_ctx_free(struct tls13_ctx *ctx)
88 {
89 	if (ctx == NULL)
90 		return;
91 
92 	tls13_record_layer_free(ctx->rl);
93 
94 	freezero(ctx, sizeof(struct tls13_ctx));
95 }
96 
97 static ssize_t
98 tls13_legacy_wire_read(SSL *ssl, uint8_t *buf, size_t len)
99 {
100 	int n;
101 
102 	if (ssl->rbio == NULL) {
103 		SSLerror(ssl, SSL_R_BIO_NOT_SET);
104 		return TLS13_IO_FAILURE;
105 	}
106 
107 	ssl->internal->rwstate = SSL_READING;
108 
109 	if ((n = BIO_read(ssl->rbio, buf, len)) <= 0) {
110 		if (BIO_should_read(ssl->rbio))
111 			return TLS13_IO_WANT_POLLIN;
112 		if (BIO_should_write(ssl->rbio))
113 			return TLS13_IO_WANT_POLLOUT;
114 
115 		return TLS13_IO_FAILURE;
116 	}
117 
118 	if (n == len)
119 		ssl->internal->rwstate = SSL_NOTHING;
120 
121 	return n;
122 }
123 
124 ssize_t
125 tls13_legacy_wire_read_cb(void *buf, size_t n, void *arg)
126 {
127 	struct tls13_ctx *ctx = arg;
128 
129 	return tls13_legacy_wire_read(ctx->ssl, buf, n);
130 }
131 
132 static ssize_t
133 tls13_legacy_wire_write(SSL *ssl, const uint8_t *buf, size_t len)
134 {
135 	int n;
136 
137 	if (ssl->wbio == NULL) {
138 		SSLerror(ssl, SSL_R_BIO_NOT_SET);
139 		return TLS13_IO_FAILURE;
140 	}
141 
142 	ssl->internal->rwstate = SSL_WRITING;
143 
144 	if ((n = BIO_write(ssl->wbio, buf, len)) <= 0) {
145 		if (BIO_should_read(ssl->wbio))
146 			return TLS13_IO_WANT_POLLIN;
147 		if (BIO_should_write(ssl->wbio))
148 			return TLS13_IO_WANT_POLLOUT;
149 
150 		return TLS13_IO_FAILURE;
151 	}
152 
153 	if (n == len)
154 		ssl->internal->rwstate = SSL_NOTHING;
155 
156 	return n;
157 }
158 
159 ssize_t
160 tls13_legacy_wire_write_cb(const void *buf, size_t n, void *arg)
161 {
162 	struct tls13_ctx *ctx = arg;
163 
164 	return tls13_legacy_wire_write(ctx->ssl, buf, n);
165 }
166 
167 int
168 tls13_legacy_return_code(SSL *ssl, ssize_t ret)
169 {
170 	if (ret > INT_MAX) {
171 		SSLerror(ssl, ERR_R_INTERNAL_ERROR);
172 		return -1;
173 	}
174 
175 	/* A successful read, write or other operation. */
176 	if (ret > 0)
177 		return ret;
178 
179 	ssl->internal->rwstate = SSL_NOTHING;
180 
181 	switch (ret) {
182 	case TLS13_IO_EOF:
183 		return 0;
184 
185 	case TLS13_IO_FAILURE:
186 		/* XXX - we need to record/map internal errors. */
187 		if (ERR_peek_error() == 0)
188 			SSLerror(ssl, ERR_R_INTERNAL_ERROR);
189 		return -1;
190 
191 	case TLS13_IO_WANT_POLLIN:
192 		ssl->internal->rwstate = SSL_READING;
193 		return -1;
194 
195 	case TLS13_IO_WANT_POLLOUT:
196 		ssl->internal->rwstate = SSL_WRITING;
197 		return -1;
198 	}
199 
200 	SSLerror(ssl, ERR_R_INTERNAL_ERROR);
201 	return -1;
202 }
203 
204 int
205 tls13_legacy_read_bytes(SSL *ssl, int type, unsigned char *buf, int len, int peek)
206 {
207 	struct tls13_ctx *ctx = ssl->internal->tls13;
208 	ssize_t ret;
209 
210 	if (peek) {
211 		/* XXX - support peek... */
212 		SSLerror(ssl, ERR_R_INTERNAL_ERROR);
213 		return -1;
214 	}
215 
216 	if (type != SSL3_RT_APPLICATION_DATA) {
217 		SSLerror(ssl, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
218 		return -1;
219 	}
220 
221 	ret = tls13_read_application_data(ctx->rl, buf, len);
222 
223 	return tls13_legacy_return_code(ssl, ret);
224 }
225 
226 int
227 tls13_legacy_write_bytes(SSL *ssl, int type, const void *buf, int len)
228 {
229 	struct tls13_ctx *ctx = ssl->internal->tls13;
230 	ssize_t ret;
231 
232 	if (type != SSL3_RT_APPLICATION_DATA) {
233 		SSLerror(ssl, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
234 		return -1;
235 	}
236 
237 	ret = tls13_write_application_data(ctx->rl, buf, len);
238 
239 	return tls13_legacy_return_code(ssl, ret);
240 }
241