linux/net/ceph/armor.c
<<
>>
Prefs
   1
   2#include <linux/errno.h>
   3
   4int ceph_armor(char *dst, const char *src, const char *end);
   5int ceph_unarmor(char *dst, const char *src, const char *end);
   6
   7/*
   8 * base64 encode/decode.
   9 */
  10
  11static const char *pem_key =
  12        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  13
  14static int encode_bits(int c)
  15{
  16        return pem_key[c];
  17}
  18
  19static int decode_bits(char c)
  20{
  21        if (c >= 'A' && c <= 'Z')
  22                return c - 'A';
  23        if (c >= 'a' && c <= 'z')
  24                return c - 'a' + 26;
  25        if (c >= '0' && c <= '9')
  26                return c - '0' + 52;
  27        if (c == '+')
  28                return 62;
  29        if (c == '/')
  30                return 63;
  31        if (c == '=')
  32                return 0; /* just non-negative, please */
  33        return -EINVAL;
  34}
  35
  36int ceph_armor(char *dst, const char *src, const char *end)
  37{
  38        int olen = 0;
  39        int line = 0;
  40
  41        while (src < end) {
  42                unsigned char a, b, c;
  43
  44                a = *src++;
  45                *dst++ = encode_bits(a >> 2);
  46                if (src < end) {
  47                        b = *src++;
  48                        *dst++ = encode_bits(((a & 3) << 4) | (b >> 4));
  49                        if (src < end) {
  50                                c = *src++;
  51                                *dst++ = encode_bits(((b & 15) << 2) |
  52                                                     (c >> 6));
  53                                *dst++ = encode_bits(c & 63);
  54                        } else {
  55                                *dst++ = encode_bits((b & 15) << 2);
  56                                *dst++ = '=';
  57                        }
  58                } else {
  59                        *dst++ = encode_bits(((a & 3) << 4));
  60                        *dst++ = '=';
  61                        *dst++ = '=';
  62                }
  63                olen += 4;
  64                line += 4;
  65                if (line == 64) {
  66                        line = 0;
  67                        *(dst++) = '\n';
  68                        olen++;
  69                }
  70        }
  71        return olen;
  72}
  73
  74int ceph_unarmor(char *dst, const char *src, const char *end)
  75{
  76        int olen = 0;
  77
  78        while (src < end) {
  79                int a, b, c, d;
  80
  81                if (src[0] == '\n') {
  82                        src++;
  83                        continue;
  84                }
  85                if (src + 4 > end)
  86                        return -EINVAL;
  87                a = decode_bits(src[0]);
  88                b = decode_bits(src[1]);
  89                c = decode_bits(src[2]);
  90                d = decode_bits(src[3]);
  91                if (a < 0 || b < 0 || c < 0 || d < 0)
  92                        return -EINVAL;
  93
  94                *dst++ = (a << 2) | (b >> 4);
  95                if (src[2] == '=')
  96                        return olen + 1;
  97                *dst++ = ((b & 15) << 4) | (c >> 2);
  98                if (src[3] == '=')
  99                        return olen + 2;
 100                *dst++ = ((c & 3) << 6) | d;
 101                olen += 3;
 102                src += 4;
 103        }
 104        return olen;
 105}
 106