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