Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
armor.c
Go to the documentation of this file.
1 
2 #include <linux/errno.h>
3 
4 int ceph_armor(char *dst, const char *src, const char *end);
5 int ceph_unarmor(char *dst, const char *src, const char *end);
6 
7 /*
8  * base64 encode/decode.
9  */
10 
11 static const char *pem_key =
12  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
13 
14 static int encode_bits(int c)
15 {
16  return pem_key[c];
17 }
18 
19 static 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 
36 int 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 
74 int 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 }