xref: /netbsd-src/external/bsd/pam-u2f/dist/fuzz/pack.c (revision 3ff1169c71051ece76f531052b2ab22d07f38c9c)
1 /* Copyright (C) 2021 Yubico AB - See COPYING */
2 #include <stdint.h>
3 #include <stddef.h>
4 #include <string.h>
5 #include <arpa/inet.h>
6 
7 #include "fuzz/fuzz.h"
8 
do_unpack(const uint8_t ** buf,size_t * rem,uint8_t * dst,size_t size)9 static int do_unpack(const uint8_t **buf, size_t *rem, uint8_t *dst,
10                      size_t size) {
11   if (*rem < size)
12     return 0;
13   memcpy(dst, *buf, size);
14   *buf += size;
15   *rem -= size;
16   return 1;
17 }
18 
do_pack(uint8_t ** buf,size_t * rem,const uint8_t * src,size_t size)19 static int do_pack(uint8_t **buf, size_t *rem, const uint8_t *src,
20                    size_t size) {
21   if (*rem < size)
22     return 0;
23   memcpy(*buf, src, size);
24   *buf += size;
25   *rem -= size;
26   return 1;
27 }
28 
pack_u32(uint8_t ** buf,size_t * rem,uint32_t val)29 int pack_u32(uint8_t **buf, size_t *rem, uint32_t val) {
30   val = htonl(val);
31   return do_pack(buf, rem, (uint8_t *) &val, sizeof(val));
32 }
33 
unpack_u32(const uint8_t ** buf,size_t * rem,uint32_t * val)34 int unpack_u32(const uint8_t **buf, size_t *rem, uint32_t *val) {
35   if (!do_unpack(buf, rem, (uint8_t *) val, sizeof(*val)))
36     return 0;
37   *val = ntohl(*val);
38   return 1;
39 }
40 
pack_blob(uint8_t ** buf,size_t * rem,const struct blob * b)41 int pack_blob(uint8_t **buf, size_t *rem, const struct blob *b) {
42   if (b->len > UINT32_MAX || b->len >= MAXBLOB)
43     return 0;
44 
45   return pack_u32(buf, rem, (uint32_t) b->len) &&
46          do_pack(buf, rem, b->body, b->len);
47 }
48 
unpack_blob(const uint8_t ** buf,size_t * rem,struct blob * b)49 int unpack_blob(const uint8_t **buf, size_t *rem, struct blob *b) {
50   uint32_t bloblen;
51 
52   if (!unpack_u32(buf, rem, &bloblen) || bloblen > MAXBLOB ||
53       !do_unpack(buf, rem, b->body, bloblen))
54     return 0;
55 
56   b->len = bloblen;
57   return 1;
58 }
59 
pack_string(uint8_t ** buf,size_t * rem,const char * s)60 int pack_string(uint8_t **buf, size_t *rem, const char *s) {
61   size_t len = strlen(s);
62 
63   if (len > UINT32_MAX || len >= MAXSTR)
64     return 0;
65 
66   return pack_u32(buf, rem, (uint32_t) len) &&
67          do_pack(buf, rem, (const uint8_t *) s, len);
68 }
69 
unpack_string(const uint8_t ** buf,size_t * rem,char * s)70 int unpack_string(const uint8_t **buf, size_t *rem, char *s) {
71   uint32_t len;
72 
73   if (!unpack_u32(buf, rem, &len) || len >= MAXSTR ||
74       !do_unpack(buf, rem, (uint8_t *) s, len))
75     return 0;
76 
77   s[len] = '\0';
78   return 1;
79 }
80