xref: /openbmc/linux/net/ceph/armor.c (revision 498495dba268b20e8eadd7fe93c140c68b6cc9d2)
1*b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
23d14c5d2SYehuda Sadeh 
33d14c5d2SYehuda Sadeh #include <linux/errno.h>
43d14c5d2SYehuda Sadeh 
53d14c5d2SYehuda Sadeh int ceph_armor(char *dst, const char *src, const char *end);
63d14c5d2SYehuda Sadeh int ceph_unarmor(char *dst, const char *src, const char *end);
73d14c5d2SYehuda Sadeh 
83d14c5d2SYehuda Sadeh /*
93d14c5d2SYehuda Sadeh  * base64 encode/decode.
103d14c5d2SYehuda Sadeh  */
113d14c5d2SYehuda Sadeh 
123d14c5d2SYehuda Sadeh static const char *pem_key =
133d14c5d2SYehuda Sadeh 	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
143d14c5d2SYehuda Sadeh 
encode_bits(int c)153d14c5d2SYehuda Sadeh static int encode_bits(int c)
163d14c5d2SYehuda Sadeh {
173d14c5d2SYehuda Sadeh 	return pem_key[c];
183d14c5d2SYehuda Sadeh }
193d14c5d2SYehuda Sadeh 
decode_bits(char c)203d14c5d2SYehuda Sadeh static int decode_bits(char c)
213d14c5d2SYehuda Sadeh {
223d14c5d2SYehuda Sadeh 	if (c >= 'A' && c <= 'Z')
233d14c5d2SYehuda Sadeh 		return c - 'A';
243d14c5d2SYehuda Sadeh 	if (c >= 'a' && c <= 'z')
253d14c5d2SYehuda Sadeh 		return c - 'a' + 26;
263d14c5d2SYehuda Sadeh 	if (c >= '0' && c <= '9')
273d14c5d2SYehuda Sadeh 		return c - '0' + 52;
283d14c5d2SYehuda Sadeh 	if (c == '+')
293d14c5d2SYehuda Sadeh 		return 62;
303d14c5d2SYehuda Sadeh 	if (c == '/')
313d14c5d2SYehuda Sadeh 		return 63;
323d14c5d2SYehuda Sadeh 	if (c == '=')
333d14c5d2SYehuda Sadeh 		return 0; /* just non-negative, please */
343d14c5d2SYehuda Sadeh 	return -EINVAL;
353d14c5d2SYehuda Sadeh }
363d14c5d2SYehuda Sadeh 
ceph_armor(char * dst,const char * src,const char * end)373d14c5d2SYehuda Sadeh int ceph_armor(char *dst, const char *src, const char *end)
383d14c5d2SYehuda Sadeh {
393d14c5d2SYehuda Sadeh 	int olen = 0;
403d14c5d2SYehuda Sadeh 	int line = 0;
413d14c5d2SYehuda Sadeh 
423d14c5d2SYehuda Sadeh 	while (src < end) {
433d14c5d2SYehuda Sadeh 		unsigned char a, b, c;
443d14c5d2SYehuda Sadeh 
453d14c5d2SYehuda Sadeh 		a = *src++;
463d14c5d2SYehuda Sadeh 		*dst++ = encode_bits(a >> 2);
473d14c5d2SYehuda Sadeh 		if (src < end) {
483d14c5d2SYehuda Sadeh 			b = *src++;
493d14c5d2SYehuda Sadeh 			*dst++ = encode_bits(((a & 3) << 4) | (b >> 4));
503d14c5d2SYehuda Sadeh 			if (src < end) {
513d14c5d2SYehuda Sadeh 				c = *src++;
523d14c5d2SYehuda Sadeh 				*dst++ = encode_bits(((b & 15) << 2) |
533d14c5d2SYehuda Sadeh 						     (c >> 6));
543d14c5d2SYehuda Sadeh 				*dst++ = encode_bits(c & 63);
553d14c5d2SYehuda Sadeh 			} else {
563d14c5d2SYehuda Sadeh 				*dst++ = encode_bits((b & 15) << 2);
573d14c5d2SYehuda Sadeh 				*dst++ = '=';
583d14c5d2SYehuda Sadeh 			}
593d14c5d2SYehuda Sadeh 		} else {
603d14c5d2SYehuda Sadeh 			*dst++ = encode_bits(((a & 3) << 4));
613d14c5d2SYehuda Sadeh 			*dst++ = '=';
623d14c5d2SYehuda Sadeh 			*dst++ = '=';
633d14c5d2SYehuda Sadeh 		}
643d14c5d2SYehuda Sadeh 		olen += 4;
653d14c5d2SYehuda Sadeh 		line += 4;
663d14c5d2SYehuda Sadeh 		if (line == 64) {
673d14c5d2SYehuda Sadeh 			line = 0;
683d14c5d2SYehuda Sadeh 			*(dst++) = '\n';
693d14c5d2SYehuda Sadeh 			olen++;
703d14c5d2SYehuda Sadeh 		}
713d14c5d2SYehuda Sadeh 	}
723d14c5d2SYehuda Sadeh 	return olen;
733d14c5d2SYehuda Sadeh }
743d14c5d2SYehuda Sadeh 
ceph_unarmor(char * dst,const char * src,const char * end)753d14c5d2SYehuda Sadeh int ceph_unarmor(char *dst, const char *src, const char *end)
763d14c5d2SYehuda Sadeh {
773d14c5d2SYehuda Sadeh 	int olen = 0;
783d14c5d2SYehuda Sadeh 
793d14c5d2SYehuda Sadeh 	while (src < end) {
803d14c5d2SYehuda Sadeh 		int a, b, c, d;
813d14c5d2SYehuda Sadeh 
82b09734b1STommi Virtanen 		if (src[0] == '\n') {
833d14c5d2SYehuda Sadeh 			src++;
84b09734b1STommi Virtanen 			continue;
85b09734b1STommi Virtanen 		}
863d14c5d2SYehuda Sadeh 		if (src + 4 > end)
873d14c5d2SYehuda Sadeh 			return -EINVAL;
883d14c5d2SYehuda Sadeh 		a = decode_bits(src[0]);
893d14c5d2SYehuda Sadeh 		b = decode_bits(src[1]);
903d14c5d2SYehuda Sadeh 		c = decode_bits(src[2]);
913d14c5d2SYehuda Sadeh 		d = decode_bits(src[3]);
923d14c5d2SYehuda Sadeh 		if (a < 0 || b < 0 || c < 0 || d < 0)
933d14c5d2SYehuda Sadeh 			return -EINVAL;
943d14c5d2SYehuda Sadeh 
953d14c5d2SYehuda Sadeh 		*dst++ = (a << 2) | (b >> 4);
963d14c5d2SYehuda Sadeh 		if (src[2] == '=')
973d14c5d2SYehuda Sadeh 			return olen + 1;
983d14c5d2SYehuda Sadeh 		*dst++ = ((b & 15) << 4) | (c >> 2);
993d14c5d2SYehuda Sadeh 		if (src[3] == '=')
1003d14c5d2SYehuda Sadeh 			return olen + 2;
1013d14c5d2SYehuda Sadeh 		*dst++ = ((c & 3) << 6) | d;
1023d14c5d2SYehuda Sadeh 		olen += 3;
1033d14c5d2SYehuda Sadeh 		src += 4;
1043d14c5d2SYehuda Sadeh 	}
1053d14c5d2SYehuda Sadeh 	return olen;
1063d14c5d2SYehuda Sadeh }
107