github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/src/tpm2/conversions.cc (about) 1 // 2 // Copyright 2014 John Manferdelli, All Rights Reserved. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // or in the the file LICENSE-2.0.txt in the top level sourcedirectory 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License 14 // Project: New Cloudproxy Crypto 15 16 #include <string> 17 #include <sys/types.h> 18 #include <sys/stat.h> 19 #include <string.h> 20 #include <stdio.h> 21 #include <tpm2_types.h> 22 23 using namespace std; 24 25 const char* websafebase64_order = 26 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; 27 28 void ThreeBytesToBase64(byte a, byte b, byte c, char* out) { 29 byte x; 30 31 x = (a >> 2) & 0x3f; 32 *out = websafebase64_order[x]; 33 x = ((a << 4) & 0x3f) | (b >> 4); 34 *(out + 1) = websafebase64_order[x]; 35 x = ((b << 2) & 0x3f) | (c >> 6); 36 *(out + 2) = websafebase64_order[x]; 37 x = c & 0x3f; 38 *(out + 3) = websafebase64_order[x]; 39 return; 40 } 41 42 void TwoBytesToBase64(byte a, byte b, char* out) { 43 byte x; 44 45 x = (a >> 2) & 0x3f; 46 *out = websafebase64_order[x]; 47 x = ((a << 4) & 0x3f) | (b >> 4); 48 *(out + 1) = websafebase64_order[x]; 49 x = (b << 2) & 0x3f; 50 *(out + 2) = websafebase64_order[x]; 51 *(out + 3) = '='; 52 return; 53 } 54 55 void OneByteToBase64(byte a, char* out) { 56 byte x; 57 58 x = a >> 2; 59 *out = websafebase64_order[x]; 60 x = (a & 0x3) << 4; 61 *(out + 1) = websafebase64_order[x]; 62 *(out + 2) = '='; 63 *(out + 3) = '='; 64 return; 65 } 66 67 int NumBase64StringInBytes(int size, byte* in) { 68 int n = (size + 3) / 3; 69 return n * 4; 70 } 71 72 int NumBytesInBase64String(char* in) { 73 if (in == nullptr) 74 return 0; 75 int j = strlen(in); 76 // j should be a multiple of 4 77 if ((j & 0x3) != 0) 78 return -1; 79 int n = (j / 4) * 3; 80 if (in[j - 1] == '=') { 81 if (in[j - 2] == '=') 82 return n - 2; 83 return n - 1; 84 } 85 return n; 86 } 87 88 byte Base64CharValue(char a) { 89 if (a >= 'A' && a <= 'Z') { 90 return a - 'A'; 91 } else if (a >= 'a' && a <= 'z') { 92 return a - 'a' + 26; 93 } else if (a >= '0' && a <= '9') { 94 return a - '0' + 52; 95 } else if (a == '-') { 96 return 62; 97 } else if (a == '_') { 98 return 63; 99 } else { 100 return 0xff; 101 } 102 } 103 104 bool FourBase64ToBytes(char* in, byte* out) { 105 byte x, y; 106 107 x = Base64CharValue(*in); 108 y = Base64CharValue(*(in + 1)); 109 if (x == 0xff || y == 0xff) 110 return false; 111 *out = (x << 2) | (y >> 4); 112 if (*(in + 2) == '=') { 113 return true; 114 } 115 x = Base64CharValue(*(in + 2)); 116 if (x == 0xff) 117 return false; 118 *(out + 1) = y << 4 | x >> 2; 119 if (*(in + 3) == '=') 120 return true; 121 y = Base64CharValue(*(in + 3)); 122 if (y == 0xff) 123 return false; 124 *(out + 2) = (x << 6) | y; 125 return true; 126 } 127 128 bool FourBase64ToBytesReverse(char* in, byte* out) { 129 byte x, y; 130 131 x = Base64CharValue(*in); 132 y = Base64CharValue(*(in + 1)); 133 if (x == 0xff || y == 0xff) 134 return false; 135 *out = (x << 2) | (y >> 4); 136 if (*(in + 2) == '=') { 137 return true; 138 } 139 x = Base64CharValue(*(in + 2)); 140 if (x == 0xff) 141 return false; 142 *(out - 1) = y << 4 | x >> 2; 143 if (*(in + 3) == '=') 144 return true; 145 y = Base64CharValue(*(in + 3)); 146 if (y == 0xff) 147 return false; 148 *(out - 2) = (x << 6) | y; 149 return true; 150 } 151 152 string* ByteToBase64LeftToRight(int size, byte* in) { 153 int n = NumBase64StringInBytes(size, in); 154 string* out = new string(n, 0); 155 char* str = (char*)out->c_str(); 156 157 if (size <= 0 || in == nullptr) 158 return nullptr; 159 while (size >= 3) { 160 ThreeBytesToBase64(*in, *(in + 1), *(in + 2), str); 161 in += 3; 162 str += 4; 163 size -= 3; 164 } 165 if (size == 2) { 166 TwoBytesToBase64(*in, *(in + 1), str); 167 in += 2; 168 str += 4; 169 size -= 2; 170 } 171 if (size == 1) { 172 OneByteToBase64(*in, str); 173 in += 1; 174 str += 4; 175 size -= 1; 176 } 177 return out; 178 } 179 180 string* ByteToBase64RightToLeft(int size, byte* in) { 181 int n = NumBase64StringInBytes(size, in); 182 string* out = new string(n, 0); 183 char* str = (char*)out->c_str(); 184 185 if (size <= 0 || in == nullptr) 186 return nullptr; 187 in += size - 1; 188 while (size >= 3) { 189 ThreeBytesToBase64(*in, *(in - 1), *(in - 2), str); 190 in -= 3; 191 str += 4; 192 size -= 3; 193 } 194 if (size == 2) { 195 TwoBytesToBase64(*in, *(in - 1), str); 196 in -= 2; 197 str += 4; 198 size -= 2; 199 } 200 if (size == 1) { 201 OneByteToBase64(*in, str); 202 in -= 1; 203 str += 4; 204 size -= 1; 205 } 206 return out; 207 } 208 209 int Base64ToByteLeftToRight(char* in, int size, byte* out) { 210 if (in == nullptr) 211 return -1; 212 213 int k = strlen(in); 214 if ((k & 0x3) != 0) 215 return -1; 216 int n = NumBytesInBase64String(in); 217 218 if (n > size) 219 return -1; 220 221 while (k > 0) { 222 FourBase64ToBytes(in, out); 223 in += 4; 224 out += 3; 225 k -= 4; 226 } 227 228 return n; 229 } 230 231 int Base64ToByteRightToLeft(char* in, int size, byte* out) { 232 if (in == nullptr) 233 return -1; 234 int k = strlen(in); 235 if ((k & 0x3) != 0) 236 return -1; 237 238 int n = NumBytesInBase64String(in); 239 if (n > size) 240 return -1; 241 242 out += n - 1; 243 while (k > 0) { 244 FourBase64ToBytesReverse(in, out); 245 in += 4; 246 out -= 3; 247 k -= 4; 248 } 249 return n; 250 } 251 252 int NumHexInBytes(int size, byte* in) { return 2 * size; } 253 254 int NumBytesInHex(char* in) { 255 if (in == nullptr) 256 return -1; 257 int len = strlen(in); 258 return ((len + 1) / 2); 259 } 260 261 char ValueToHex(byte x) { 262 if (x >= 0 && x <= 9) { 263 return x + '0'; 264 } else if (x >= 10 && x <= 15) { 265 return x - 10 + 'a'; 266 } else { 267 return ' '; 268 } 269 } 270 271 byte HexToValue(char x) { 272 if (x >= '0' && x <= '9') { 273 return x - '0'; 274 } else if (x >= 'a' && x <= 'f') { 275 return x + 10 - 'a'; 276 } else { 277 return 0; 278 } 279 } 280 281 string* ByteToHexLeftToRight(int size, byte* in) { 282 if (in == nullptr) 283 return nullptr; 284 int n = NumHexInBytes(size, in); 285 string* out = new string(n, 0); 286 char* str = (char*)out->c_str(); 287 byte a, b; 288 289 while (size > 0) { 290 a = (*in) >> 4; 291 b = (*in) & 0xf; 292 in++; 293 *(str++) = ValueToHex(a); 294 *(str++) = ValueToHex(b); 295 size--; 296 } 297 return out; 298 } 299 300 int HexToByteLeftToRight(char* in, int size, byte* out) { 301 if (in == nullptr) 302 return -1; 303 int n = NumBytesInHex(in); 304 int m = strlen(in); 305 byte a, b; 306 307 if (n > size) { 308 return -1; 309 } 310 while (m > 0) { 311 a = HexToValue(*(in++)); 312 b = HexToValue(*(in++)); 313 *(out++) = (a << 4) | b; 314 m -= 2; 315 } 316 return n; 317 } 318 319 string* ByteToHexRightToLeft(int size, byte* in) { 320 if (in == nullptr) 321 return nullptr; 322 int n = NumHexInBytes(size, in); 323 string* out = new string(n, 0); 324 char* str = (char*)out->c_str(); 325 byte a, b; 326 327 in += size - 1; 328 while (size > 0) { 329 a = (*in) >> 4; 330 b = (*in) & 0xf; 331 in--; 332 *(str++) = ValueToHex(a); 333 *(str++) = ValueToHex(b); 334 size--; 335 } 336 return out; 337 } 338 339 int HexToByteRightToLeft(char* in, int size, byte* out) { 340 if (in == nullptr) { 341 return -1; 342 } 343 int n = NumBytesInHex(in); 344 int m = strlen(in); 345 byte a, b; 346 347 out += n - 1; 348 if (m < 0) { 349 return -1; 350 } 351 while (m > 0) { 352 a = HexToValue(*(in++)); 353 b = HexToValue(*(in++)); 354 *(out--) = (a << 4) | b; 355 m -= 2; 356 } 357 return n; 358 }