xref: /freebsd/crypto/openssh/openbsd-compat/base64.c (revision 1323ec571215a77ddd21294f0871979d5ad6b992)
1d4af9e69SDag-Erling Smørgrav /*	$OpenBSD: base64.c,v 1.5 2006/10/21 09:55:03 otto Exp $	*/
283d2307dSDag-Erling Smørgrav 
383d2307dSDag-Erling Smørgrav /*
483d2307dSDag-Erling Smørgrav  * Copyright (c) 1996 by Internet Software Consortium.
583d2307dSDag-Erling Smørgrav  *
683d2307dSDag-Erling Smørgrav  * Permission to use, copy, modify, and distribute this software for any
783d2307dSDag-Erling Smørgrav  * purpose with or without fee is hereby granted, provided that the above
883d2307dSDag-Erling Smørgrav  * copyright notice and this permission notice appear in all copies.
983d2307dSDag-Erling Smørgrav  *
1083d2307dSDag-Erling Smørgrav  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
1183d2307dSDag-Erling Smørgrav  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
1283d2307dSDag-Erling Smørgrav  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
1383d2307dSDag-Erling Smørgrav  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
1483d2307dSDag-Erling Smørgrav  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
1583d2307dSDag-Erling Smørgrav  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
1683d2307dSDag-Erling Smørgrav  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
1783d2307dSDag-Erling Smørgrav  * SOFTWARE.
1883d2307dSDag-Erling Smørgrav  */
1983d2307dSDag-Erling Smørgrav 
2083d2307dSDag-Erling Smørgrav /*
2183d2307dSDag-Erling Smørgrav  * Portions Copyright (c) 1995 by International Business Machines, Inc.
2283d2307dSDag-Erling Smørgrav  *
2383d2307dSDag-Erling Smørgrav  * International Business Machines, Inc. (hereinafter called IBM) grants
2483d2307dSDag-Erling Smørgrav  * permission under its copyrights to use, copy, modify, and distribute this
2583d2307dSDag-Erling Smørgrav  * Software with or without fee, provided that the above copyright notice and
2683d2307dSDag-Erling Smørgrav  * all paragraphs of this notice appear in all copies, and that the name of IBM
2783d2307dSDag-Erling Smørgrav  * not be used in connection with the marketing of any product incorporating
2883d2307dSDag-Erling Smørgrav  * the Software or modifications thereof, without specific, written prior
2983d2307dSDag-Erling Smørgrav  * permission.
3083d2307dSDag-Erling Smørgrav  *
3183d2307dSDag-Erling Smørgrav  * To the extent it has a right to do so, IBM grants an immunity from suit
3283d2307dSDag-Erling Smørgrav  * under its patents, if any, for the use, sale or manufacture of products to
3383d2307dSDag-Erling Smørgrav  * the extent that such products are used for performing Domain Name System
3483d2307dSDag-Erling Smørgrav  * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
3583d2307dSDag-Erling Smørgrav  * granted for any product per se or for any other function of any product.
3683d2307dSDag-Erling Smørgrav  *
3783d2307dSDag-Erling Smørgrav  * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
3883d2307dSDag-Erling Smørgrav  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
3983d2307dSDag-Erling Smørgrav  * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
4083d2307dSDag-Erling Smørgrav  * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
4183d2307dSDag-Erling Smørgrav  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
4283d2307dSDag-Erling Smørgrav  * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
4383d2307dSDag-Erling Smørgrav  */
4483d2307dSDag-Erling Smørgrav 
45021d409fSDag-Erling Smørgrav /* OPENBSD ORIGINAL: lib/libc/net/base64.c */
46021d409fSDag-Erling Smørgrav 
474b17dab0SDag-Erling Smørgrav #include "includes.h"
4883d2307dSDag-Erling Smørgrav 
49d0c8c0bcSDag-Erling Smørgrav #if (!defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP)) || (!defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON))
5083d2307dSDag-Erling Smørgrav 
5183d2307dSDag-Erling Smørgrav #include <sys/types.h>
5283d2307dSDag-Erling Smørgrav #include <sys/socket.h>
5383d2307dSDag-Erling Smørgrav #include <netinet/in.h>
5483d2307dSDag-Erling Smørgrav #include <arpa/inet.h>
5583d2307dSDag-Erling Smørgrav 
5683d2307dSDag-Erling Smørgrav #include <ctype.h>
5783d2307dSDag-Erling Smørgrav #include <stdio.h>
5883d2307dSDag-Erling Smørgrav 
5983d2307dSDag-Erling Smørgrav #include <stdlib.h>
6083d2307dSDag-Erling Smørgrav #include <string.h>
6183d2307dSDag-Erling Smørgrav 
6283d2307dSDag-Erling Smørgrav #include "base64.h"
6383d2307dSDag-Erling Smørgrav 
6483d2307dSDag-Erling Smørgrav static const char Base64[] =
6583d2307dSDag-Erling Smørgrav 	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
6683d2307dSDag-Erling Smørgrav static const char Pad64 = '=';
6783d2307dSDag-Erling Smørgrav 
6883d2307dSDag-Erling Smørgrav /* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
6983d2307dSDag-Erling Smørgrav    The following encoding technique is taken from RFC 1521 by Borenstein
7083d2307dSDag-Erling Smørgrav    and Freed.  It is reproduced here in a slightly edited form for
7183d2307dSDag-Erling Smørgrav    convenience.
7283d2307dSDag-Erling Smørgrav 
7383d2307dSDag-Erling Smørgrav    A 65-character subset of US-ASCII is used, enabling 6 bits to be
7483d2307dSDag-Erling Smørgrav    represented per printable character. (The extra 65th character, "=",
7583d2307dSDag-Erling Smørgrav    is used to signify a special processing function.)
7683d2307dSDag-Erling Smørgrav 
7783d2307dSDag-Erling Smørgrav    The encoding process represents 24-bit groups of input bits as output
7883d2307dSDag-Erling Smørgrav    strings of 4 encoded characters. Proceeding from left to right, a
7983d2307dSDag-Erling Smørgrav    24-bit input group is formed by concatenating 3 8-bit input groups.
8083d2307dSDag-Erling Smørgrav    These 24 bits are then treated as 4 concatenated 6-bit groups, each
8183d2307dSDag-Erling Smørgrav    of which is translated into a single digit in the base64 alphabet.
8283d2307dSDag-Erling Smørgrav 
8383d2307dSDag-Erling Smørgrav    Each 6-bit group is used as an index into an array of 64 printable
8483d2307dSDag-Erling Smørgrav    characters. The character referenced by the index is placed in the
8583d2307dSDag-Erling Smørgrav    output string.
8683d2307dSDag-Erling Smørgrav 
8783d2307dSDag-Erling Smørgrav                          Table 1: The Base64 Alphabet
8883d2307dSDag-Erling Smørgrav 
8983d2307dSDag-Erling Smørgrav       Value Encoding  Value Encoding  Value Encoding  Value Encoding
9083d2307dSDag-Erling Smørgrav           0 A            17 R            34 i            51 z
9183d2307dSDag-Erling Smørgrav           1 B            18 S            35 j            52 0
9283d2307dSDag-Erling Smørgrav           2 C            19 T            36 k            53 1
9383d2307dSDag-Erling Smørgrav           3 D            20 U            37 l            54 2
9483d2307dSDag-Erling Smørgrav           4 E            21 V            38 m            55 3
9583d2307dSDag-Erling Smørgrav           5 F            22 W            39 n            56 4
9683d2307dSDag-Erling Smørgrav           6 G            23 X            40 o            57 5
9783d2307dSDag-Erling Smørgrav           7 H            24 Y            41 p            58 6
9883d2307dSDag-Erling Smørgrav           8 I            25 Z            42 q            59 7
9983d2307dSDag-Erling Smørgrav           9 J            26 a            43 r            60 8
10083d2307dSDag-Erling Smørgrav          10 K            27 b            44 s            61 9
10183d2307dSDag-Erling Smørgrav          11 L            28 c            45 t            62 +
10283d2307dSDag-Erling Smørgrav          12 M            29 d            46 u            63 /
10383d2307dSDag-Erling Smørgrav          13 N            30 e            47 v
10483d2307dSDag-Erling Smørgrav          14 O            31 f            48 w         (pad) =
10583d2307dSDag-Erling Smørgrav          15 P            32 g            49 x
10683d2307dSDag-Erling Smørgrav          16 Q            33 h            50 y
10783d2307dSDag-Erling Smørgrav 
10883d2307dSDag-Erling Smørgrav    Special processing is performed if fewer than 24 bits are available
10983d2307dSDag-Erling Smørgrav    at the end of the data being encoded.  A full encoding quantum is
11083d2307dSDag-Erling Smørgrav    always completed at the end of a quantity.  When fewer than 24 input
11183d2307dSDag-Erling Smørgrav    bits are available in an input group, zero bits are added (on the
11283d2307dSDag-Erling Smørgrav    right) to form an integral number of 6-bit groups.  Padding at the
11383d2307dSDag-Erling Smørgrav    end of the data is performed using the '=' character.
11483d2307dSDag-Erling Smørgrav 
11583d2307dSDag-Erling Smørgrav    Since all base64 input is an integral number of octets, only the
11683d2307dSDag-Erling Smørgrav          -------------------------------------------------
11783d2307dSDag-Erling Smørgrav    following cases can arise:
11883d2307dSDag-Erling Smørgrav 
11983d2307dSDag-Erling Smørgrav        (1) the final quantum of encoding input is an integral
12083d2307dSDag-Erling Smørgrav            multiple of 24 bits; here, the final unit of encoded
12183d2307dSDag-Erling Smørgrav 	   output will be an integral multiple of 4 characters
12283d2307dSDag-Erling Smørgrav 	   with no "=" padding,
12383d2307dSDag-Erling Smørgrav        (2) the final quantum of encoding input is exactly 8 bits;
12483d2307dSDag-Erling Smørgrav            here, the final unit of encoded output will be two
12583d2307dSDag-Erling Smørgrav 	   characters followed by two "=" padding characters, or
12683d2307dSDag-Erling Smørgrav        (3) the final quantum of encoding input is exactly 16 bits;
12783d2307dSDag-Erling Smørgrav            here, the final unit of encoded output will be three
12883d2307dSDag-Erling Smørgrav 	   characters followed by one "=" padding character.
12983d2307dSDag-Erling Smørgrav    */
13083d2307dSDag-Erling Smørgrav 
131d0c8c0bcSDag-Erling Smørgrav #if !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP)
13283d2307dSDag-Erling Smørgrav int
b64_ntop(u_char const * src,size_t srclength,char * target,size_t targsize)13383d2307dSDag-Erling Smørgrav b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize)
13483d2307dSDag-Erling Smørgrav {
13583d2307dSDag-Erling Smørgrav 	size_t datalength = 0;
13683d2307dSDag-Erling Smørgrav 	u_char input[3];
13783d2307dSDag-Erling Smørgrav 	u_char output[4];
138021d409fSDag-Erling Smørgrav 	u_int i;
13983d2307dSDag-Erling Smørgrav 
14083d2307dSDag-Erling Smørgrav 	while (2 < srclength) {
14183d2307dSDag-Erling Smørgrav 		input[0] = *src++;
14283d2307dSDag-Erling Smørgrav 		input[1] = *src++;
14383d2307dSDag-Erling Smørgrav 		input[2] = *src++;
14483d2307dSDag-Erling Smørgrav 		srclength -= 3;
14583d2307dSDag-Erling Smørgrav 
14683d2307dSDag-Erling Smørgrav 		output[0] = input[0] >> 2;
14783d2307dSDag-Erling Smørgrav 		output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
14883d2307dSDag-Erling Smørgrav 		output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
14983d2307dSDag-Erling Smørgrav 		output[3] = input[2] & 0x3f;
15083d2307dSDag-Erling Smørgrav 
15183d2307dSDag-Erling Smørgrav 		if (datalength + 4 > targsize)
15283d2307dSDag-Erling Smørgrav 			return (-1);
15383d2307dSDag-Erling Smørgrav 		target[datalength++] = Base64[output[0]];
15483d2307dSDag-Erling Smørgrav 		target[datalength++] = Base64[output[1]];
15583d2307dSDag-Erling Smørgrav 		target[datalength++] = Base64[output[2]];
15683d2307dSDag-Erling Smørgrav 		target[datalength++] = Base64[output[3]];
15783d2307dSDag-Erling Smørgrav 	}
15883d2307dSDag-Erling Smørgrav 
15983d2307dSDag-Erling Smørgrav 	/* Now we worry about padding. */
16083d2307dSDag-Erling Smørgrav 	if (0 != srclength) {
16183d2307dSDag-Erling Smørgrav 		/* Get what's left. */
16283d2307dSDag-Erling Smørgrav 		input[0] = input[1] = input[2] = '\0';
16383d2307dSDag-Erling Smørgrav 		for (i = 0; i < srclength; i++)
16483d2307dSDag-Erling Smørgrav 			input[i] = *src++;
16583d2307dSDag-Erling Smørgrav 
16683d2307dSDag-Erling Smørgrav 		output[0] = input[0] >> 2;
16783d2307dSDag-Erling Smørgrav 		output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
16883d2307dSDag-Erling Smørgrav 		output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
16983d2307dSDag-Erling Smørgrav 
17083d2307dSDag-Erling Smørgrav 		if (datalength + 4 > targsize)
17183d2307dSDag-Erling Smørgrav 			return (-1);
17283d2307dSDag-Erling Smørgrav 		target[datalength++] = Base64[output[0]];
17383d2307dSDag-Erling Smørgrav 		target[datalength++] = Base64[output[1]];
17483d2307dSDag-Erling Smørgrav 		if (srclength == 1)
17583d2307dSDag-Erling Smørgrav 			target[datalength++] = Pad64;
17683d2307dSDag-Erling Smørgrav 		else
17783d2307dSDag-Erling Smørgrav 			target[datalength++] = Base64[output[2]];
17883d2307dSDag-Erling Smørgrav 		target[datalength++] = Pad64;
17983d2307dSDag-Erling Smørgrav 	}
18083d2307dSDag-Erling Smørgrav 	if (datalength >= targsize)
18183d2307dSDag-Erling Smørgrav 		return (-1);
18283d2307dSDag-Erling Smørgrav 	target[datalength] = '\0';	/* Returned value doesn't count \0. */
18383d2307dSDag-Erling Smørgrav 	return (datalength);
18483d2307dSDag-Erling Smørgrav }
185d0c8c0bcSDag-Erling Smørgrav #endif /* !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) */
186d0c8c0bcSDag-Erling Smørgrav 
187d0c8c0bcSDag-Erling Smørgrav #if !defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON)
18883d2307dSDag-Erling Smørgrav 
18983d2307dSDag-Erling Smørgrav /* skips all whitespace anywhere.
19083d2307dSDag-Erling Smørgrav    converts characters, four at a time, starting at (or after)
19183d2307dSDag-Erling Smørgrav    src from base - 64 numbers into three 8 bit bytes in the target area.
19283d2307dSDag-Erling Smørgrav    it returns the number of data bytes stored at the target, or -1 on error.
19383d2307dSDag-Erling Smørgrav  */
19483d2307dSDag-Erling Smørgrav 
19583d2307dSDag-Erling Smørgrav int
b64_pton(char const * src,u_char * target,size_t targsize)19683d2307dSDag-Erling Smørgrav b64_pton(char const *src, u_char *target, size_t targsize)
19783d2307dSDag-Erling Smørgrav {
198021d409fSDag-Erling Smørgrav 	u_int tarindex, state;
199021d409fSDag-Erling Smørgrav 	int ch;
20083d2307dSDag-Erling Smørgrav 	char *pos;
20183d2307dSDag-Erling Smørgrav 
20283d2307dSDag-Erling Smørgrav 	state = 0;
20383d2307dSDag-Erling Smørgrav 	tarindex = 0;
20483d2307dSDag-Erling Smørgrav 
20583d2307dSDag-Erling Smørgrav 	while ((ch = *src++) != '\0') {
20683d2307dSDag-Erling Smørgrav 		if (isspace(ch))	/* Skip whitespace anywhere. */
20783d2307dSDag-Erling Smørgrav 			continue;
20883d2307dSDag-Erling Smørgrav 
20983d2307dSDag-Erling Smørgrav 		if (ch == Pad64)
21083d2307dSDag-Erling Smørgrav 			break;
21183d2307dSDag-Erling Smørgrav 
21283d2307dSDag-Erling Smørgrav 		pos = strchr(Base64, ch);
21383d2307dSDag-Erling Smørgrav 		if (pos == 0)		/* A non-base64 character. */
21483d2307dSDag-Erling Smørgrav 			return (-1);
21583d2307dSDag-Erling Smørgrav 
21683d2307dSDag-Erling Smørgrav 		switch (state) {
21783d2307dSDag-Erling Smørgrav 		case 0:
21883d2307dSDag-Erling Smørgrav 			if (target) {
21983d2307dSDag-Erling Smørgrav 				if (tarindex >= targsize)
22083d2307dSDag-Erling Smørgrav 					return (-1);
22183d2307dSDag-Erling Smørgrav 				target[tarindex] = (pos - Base64) << 2;
22283d2307dSDag-Erling Smørgrav 			}
22383d2307dSDag-Erling Smørgrav 			state = 1;
22483d2307dSDag-Erling Smørgrav 			break;
22583d2307dSDag-Erling Smørgrav 		case 1:
22683d2307dSDag-Erling Smørgrav 			if (target) {
22783d2307dSDag-Erling Smørgrav 				if (tarindex + 1 >= targsize)
22883d2307dSDag-Erling Smørgrav 					return (-1);
22983d2307dSDag-Erling Smørgrav 				target[tarindex]   |=  (pos - Base64) >> 4;
23083d2307dSDag-Erling Smørgrav 				target[tarindex+1]  = ((pos - Base64) & 0x0f)
23183d2307dSDag-Erling Smørgrav 							<< 4 ;
23283d2307dSDag-Erling Smørgrav 			}
23383d2307dSDag-Erling Smørgrav 			tarindex++;
23483d2307dSDag-Erling Smørgrav 			state = 2;
23583d2307dSDag-Erling Smørgrav 			break;
23683d2307dSDag-Erling Smørgrav 		case 2:
23783d2307dSDag-Erling Smørgrav 			if (target) {
23883d2307dSDag-Erling Smørgrav 				if (tarindex + 1 >= targsize)
23983d2307dSDag-Erling Smørgrav 					return (-1);
24083d2307dSDag-Erling Smørgrav 				target[tarindex]   |=  (pos - Base64) >> 2;
24183d2307dSDag-Erling Smørgrav 				target[tarindex+1]  = ((pos - Base64) & 0x03)
24283d2307dSDag-Erling Smørgrav 							<< 6;
24383d2307dSDag-Erling Smørgrav 			}
24483d2307dSDag-Erling Smørgrav 			tarindex++;
24583d2307dSDag-Erling Smørgrav 			state = 3;
24683d2307dSDag-Erling Smørgrav 			break;
24783d2307dSDag-Erling Smørgrav 		case 3:
24883d2307dSDag-Erling Smørgrav 			if (target) {
24983d2307dSDag-Erling Smørgrav 				if (tarindex >= targsize)
25083d2307dSDag-Erling Smørgrav 					return (-1);
25183d2307dSDag-Erling Smørgrav 				target[tarindex] |= (pos - Base64);
25283d2307dSDag-Erling Smørgrav 			}
25383d2307dSDag-Erling Smørgrav 			tarindex++;
25483d2307dSDag-Erling Smørgrav 			state = 0;
25583d2307dSDag-Erling Smørgrav 			break;
25683d2307dSDag-Erling Smørgrav 		}
25783d2307dSDag-Erling Smørgrav 	}
25883d2307dSDag-Erling Smørgrav 
25983d2307dSDag-Erling Smørgrav 	/*
26083d2307dSDag-Erling Smørgrav 	 * We are done decoding Base-64 chars.  Let's see if we ended
26183d2307dSDag-Erling Smørgrav 	 * on a byte boundary, and/or with erroneous trailing characters.
26283d2307dSDag-Erling Smørgrav 	 */
26383d2307dSDag-Erling Smørgrav 
26483d2307dSDag-Erling Smørgrav 	if (ch == Pad64) {		/* We got a pad char. */
26583d2307dSDag-Erling Smørgrav 		ch = *src++;		/* Skip it, get next. */
26683d2307dSDag-Erling Smørgrav 		switch (state) {
26783d2307dSDag-Erling Smørgrav 		case 0:		/* Invalid = in first position */
26883d2307dSDag-Erling Smørgrav 		case 1:		/* Invalid = in second position */
26983d2307dSDag-Erling Smørgrav 			return (-1);
27083d2307dSDag-Erling Smørgrav 
27183d2307dSDag-Erling Smørgrav 		case 2:		/* Valid, means one byte of info */
27283d2307dSDag-Erling Smørgrav 			/* Skip any number of spaces. */
27383d2307dSDag-Erling Smørgrav 			for (; ch != '\0'; ch = *src++)
27483d2307dSDag-Erling Smørgrav 				if (!isspace(ch))
27583d2307dSDag-Erling Smørgrav 					break;
27683d2307dSDag-Erling Smørgrav 			/* Make sure there is another trailing = sign. */
27783d2307dSDag-Erling Smørgrav 			if (ch != Pad64)
27883d2307dSDag-Erling Smørgrav 				return (-1);
27983d2307dSDag-Erling Smørgrav 			ch = *src++;		/* Skip the = */
28083d2307dSDag-Erling Smørgrav 			/* Fall through to "single trailing =" case. */
28183d2307dSDag-Erling Smørgrav 			/* FALLTHROUGH */
28283d2307dSDag-Erling Smørgrav 
28383d2307dSDag-Erling Smørgrav 		case 3:		/* Valid, means two bytes of info */
28483d2307dSDag-Erling Smørgrav 			/*
28583d2307dSDag-Erling Smørgrav 			 * We know this char is an =.  Is there anything but
28683d2307dSDag-Erling Smørgrav 			 * whitespace after it?
28783d2307dSDag-Erling Smørgrav 			 */
28883d2307dSDag-Erling Smørgrav 			for (; ch != '\0'; ch = *src++)
28983d2307dSDag-Erling Smørgrav 				if (!isspace(ch))
29083d2307dSDag-Erling Smørgrav 					return (-1);
29183d2307dSDag-Erling Smørgrav 
29283d2307dSDag-Erling Smørgrav 			/*
29383d2307dSDag-Erling Smørgrav 			 * Now make sure for cases 2 and 3 that the "extra"
29483d2307dSDag-Erling Smørgrav 			 * bits that slopped past the last full byte were
29583d2307dSDag-Erling Smørgrav 			 * zeros.  If we don't check them, they become a
29683d2307dSDag-Erling Smørgrav 			 * subliminal channel.
29783d2307dSDag-Erling Smørgrav 			 */
29883d2307dSDag-Erling Smørgrav 			if (target && target[tarindex] != 0)
29983d2307dSDag-Erling Smørgrav 				return (-1);
30083d2307dSDag-Erling Smørgrav 		}
30183d2307dSDag-Erling Smørgrav 	} else {
30283d2307dSDag-Erling Smørgrav 		/*
30383d2307dSDag-Erling Smørgrav 		 * We ended by seeing the end of the string.  Make sure we
30483d2307dSDag-Erling Smørgrav 		 * have no partial bytes lying around.
30583d2307dSDag-Erling Smørgrav 		 */
30683d2307dSDag-Erling Smørgrav 		if (state != 0)
30783d2307dSDag-Erling Smørgrav 			return (-1);
30883d2307dSDag-Erling Smørgrav 	}
30983d2307dSDag-Erling Smørgrav 
31083d2307dSDag-Erling Smørgrav 	return (tarindex);
31183d2307dSDag-Erling Smørgrav }
31283d2307dSDag-Erling Smørgrav 
313d0c8c0bcSDag-Erling Smørgrav #endif /* !defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON) */
314d0c8c0bcSDag-Erling Smørgrav #endif
315