Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
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  * base64 encode/decode.
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; /* just non-negative, please */
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 }