0001
0002
0003 #include <linux/errno.h>
0004
0005 int ceph_armor(char *dst, const char *src, const char *end);
0006 int ceph_unarmor(char *dst, const char *src, const char *end);
0007
0008
0009
0010
0011
0012 static const char *pem_key =
0013 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
0014
0015 static int encode_bits(int c)
0016 {
0017 return pem_key[c];
0018 }
0019
0020 static int decode_bits(char c)
0021 {
0022 if (c >= 'A' && c <= 'Z')
0023 return c - 'A';
0024 if (c >= 'a' && c <= 'z')
0025 return c - 'a' + 26;
0026 if (c >= '0' && c <= '9')
0027 return c - '0' + 52;
0028 if (c == '+')
0029 return 62;
0030 if (c == '/')
0031 return 63;
0032 if (c == '=')
0033 return 0;
0034 return -EINVAL;
0035 }
0036
0037 int ceph_armor(char *dst, const char *src, const char *end)
0038 {
0039 int olen = 0;
0040 int line = 0;
0041
0042 while (src < end) {
0043 unsigned char a, b, c;
0044
0045 a = *src++;
0046 *dst++ = encode_bits(a >> 2);
0047 if (src < end) {
0048 b = *src++;
0049 *dst++ = encode_bits(((a & 3) << 4) | (b >> 4));
0050 if (src < end) {
0051 c = *src++;
0052 *dst++ = encode_bits(((b & 15) << 2) |
0053 (c >> 6));
0054 *dst++ = encode_bits(c & 63);
0055 } else {
0056 *dst++ = encode_bits((b & 15) << 2);
0057 *dst++ = '=';
0058 }
0059 } else {
0060 *dst++ = encode_bits(((a & 3) << 4));
0061 *dst++ = '=';
0062 *dst++ = '=';
0063 }
0064 olen += 4;
0065 line += 4;
0066 if (line == 64) {
0067 line = 0;
0068 *(dst++) = '\n';
0069 olen++;
0070 }
0071 }
0072 return olen;
0073 }
0074
0075 int ceph_unarmor(char *dst, const char *src, const char *end)
0076 {
0077 int olen = 0;
0078
0079 while (src < end) {
0080 int a, b, c, d;
0081
0082 if (src[0] == '\n') {
0083 src++;
0084 continue;
0085 }
0086 if (src + 4 > end)
0087 return -EINVAL;
0088 a = decode_bits(src[0]);
0089 b = decode_bits(src[1]);
0090 c = decode_bits(src[2]);
0091 d = decode_bits(src[3]);
0092 if (a < 0 || b < 0 || c < 0 || d < 0)
0093 return -EINVAL;
0094
0095 *dst++ = (a << 2) | (b >> 4);
0096 if (src[2] == '=')
0097 return olen + 1;
0098 *dst++ = ((b & 15) << 4) | (c >> 2);
0099 if (src[3] == '=')
0100 return olen + 2;
0101 *dst++ = ((c & 3) << 6) | d;
0102 olen += 3;
0103 src += 4;
0104 }
0105 return olen;
0106 }