OpenOCD
base64.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: BSD-3-Clause
2 
3 /*
4  * Base64 encoding/decoding (RFC1341)
5  * Copyright (c) 2005-2011, Jouni Malinen <j@w1.fi>
6  *
7  * Original file from FreeBSD code
8  * https://cgit.freebsd.org/src/tree/contrib/wpa/src/utils/base64.c?id=f05cddf940db
9  */
10 
11 
12 #include <stddef.h>
13 #include <stdlib.h>
14 #include <string.h>
15 
16 #include "base64.h"
17 
18 static const unsigned char base64_table[65] =
19  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
20 
33 unsigned char *base64_encode(const unsigned char *src, size_t len,
34  size_t *out_len)
35 {
36  unsigned char *out, *pos;
37  const unsigned char *end, *in;
38  size_t olen;
39  int line_len;
40 
41  olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
42  olen += olen / 72; /* line feeds */
43  olen++; /* nul termination */
44  if (olen < len)
45  return NULL; /* integer overflow */
46  out = malloc(olen);
47  if (!out)
48  return NULL;
49 
50  end = src + len;
51  in = src;
52  pos = out;
53  line_len = 0;
54  while (end - in >= 3) {
55  *pos++ = base64_table[in[0] >> 2];
56  *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
57  *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
58  *pos++ = base64_table[in[2] & 0x3f];
59  in += 3;
60  line_len += 4;
61  if (line_len >= 72) {
62  *pos++ = '\n';
63  line_len = 0;
64  }
65  }
66 
67  if (end - in) {
68  *pos++ = base64_table[in[0] >> 2];
69  if (end - in == 1) {
70  *pos++ = base64_table[(in[0] & 0x03) << 4];
71  *pos++ = '=';
72  } else {
73  *pos++ = base64_table[((in[0] & 0x03) << 4) |
74  (in[1] >> 4)];
75  *pos++ = base64_table[(in[1] & 0x0f) << 2];
76  }
77  *pos++ = '=';
78  line_len += 4;
79  }
80 
81  if (line_len)
82  *pos++ = '\n';
83 
84  *pos = '\0';
85  if (out_len)
86  *out_len = pos - out;
87  return out;
88 }
89 
90 
101 unsigned char *base64_decode(const unsigned char *src, size_t len,
102  size_t *out_len)
103 {
104  unsigned char dtable[256], *out, *pos, block[4], tmp;
105  size_t i, count, olen;
106  int pad = 0;
107 
108  memset(dtable, 0x80, 256);
109  for (i = 0; i < sizeof(base64_table) - 1; i++)
110  dtable[base64_table[i]] = (unsigned char)i;
111  dtable['='] = 0;
112 
113  count = 0;
114  for (i = 0; i < len; i++) {
115  if (dtable[src[i]] != 0x80)
116  count++;
117  }
118 
119  if (count == 0 || count % 4)
120  return NULL;
121 
122  olen = count / 4 * 3;
123  out = malloc(olen);
124  if (!out)
125  return NULL;
126  pos = out;
127 
128  count = 0;
129  for (i = 0; i < len; i++) {
130  tmp = dtable[src[i]];
131  if (tmp == 0x80)
132  continue;
133 
134  if (src[i] == '=')
135  pad++;
136  block[count] = tmp;
137  count++;
138  if (count == 4) {
139  *pos++ = (block[0] << 2) | (block[1] >> 4);
140  *pos++ = (block[1] << 4) | (block[2] >> 2);
141  *pos++ = (block[2] << 6) | block[3];
142  count = 0;
143  if (pad) {
144  if (pad == 1) {
145  pos--;
146  } else if (pad == 2) {
147  pos -= 2;
148  } else {
149  /* Invalid padding */
150  free(out);
151  return NULL;
152  }
153  break;
154  }
155  }
156  }
157 
158  *out_len = pos - out;
159  return out;
160 }
static const unsigned char base64_table[65]
Definition: base64.c:18
unsigned char * base64_decode(const unsigned char *src, size_t len, size_t *out_len)
base64_decode - Base64 decode @src: Data to be decoded @len: Length of the data to be decoded @out_le...
Definition: base64.c:101
unsigned char * base64_encode(const unsigned char *src, size_t len, size_t *out_len)
base64_encode - Base64 encode @src: Data to be encoded @len: Length of the data to be encoded @out_le...
Definition: base64.c:33
#define NULL
Definition: usb.h:16
uint8_t count[4]
Definition: vdebug.c:22