xref: /freebsd/contrib/libfido2/src/compress.c (revision 8bab661a3316d8bd9b9fbd11a3b4371b91507bd2)
1 /*
2  * Copyright (c) 2020 Yubico AB. All rights reserved.
3  * Use of this source code is governed by a BSD-style
4  * license that can be found in the LICENSE file.
5  */
6 
7 #include <zlib.h>
8 #include "fido.h"
9 
10 #define BOUND (1024UL * 1024UL)
11 
12 static int
13 do_compress(fido_blob_t *out, const fido_blob_t *in, size_t origsiz, int decomp)
14 {
15 	u_long ilen, olen;
16 	int r;
17 
18 	memset(out, 0, sizeof(*out));
19 	if (in->len > ULONG_MAX || (ilen = (u_long)in->len) > BOUND ||
20 	    origsiz > ULONG_MAX || (olen = decomp ? (u_long)origsiz :
21 	    compressBound(ilen)) > BOUND)
22 		return FIDO_ERR_INVALID_ARGUMENT;
23 	if ((out->ptr = calloc(1, olen)) == NULL)
24 		return FIDO_ERR_INTERNAL;
25 	out->len = olen;
26 	if (decomp)
27 		r = uncompress(out->ptr, &olen, in->ptr, ilen);
28 	else
29 		r = compress(out->ptr, &olen, in->ptr, ilen);
30 	if (r != Z_OK || olen > SIZE_MAX || olen > out->len) {
31 		fido_blob_reset(out);
32 		return FIDO_ERR_COMPRESS;
33 	}
34 	out->len = olen;
35 
36 	return FIDO_OK;
37 }
38 
39 int
40 fido_compress(fido_blob_t *out, const fido_blob_t *in)
41 {
42 	return do_compress(out, in, 0, 0);
43 }
44 
45 int
46 fido_uncompress(fido_blob_t *out, const fido_blob_t *in, size_t origsiz)
47 {
48 	return do_compress(out, in, origsiz, 1);
49 }
50