Blame view

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