• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 The Android Open Source Project
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  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "debug.h"
18 #include "hexbin.h"
19 
20 #include <openssl/base64.h>
21 
22 namespace aidl {
23 namespace android {
24 namespace hardware {
25 namespace radio {
26 namespace implementation {
27 
hex2bin1(const char c)28 uint8_t hex2bin1(const char c) {
29     if ((c >= '0') && (c <= '9')) {
30         return c - '0';
31     } else if ((c >= 'a') && (c <= 'f')) {
32         return c - 'a' + 10;
33     } else if ((c >= 'A') && (c <= 'F')) {
34         return c - 'A' + 10;
35     } else {
36         return 0;
37     }
38 }
39 
hex2binImpl(const char * s,uint8_t * b,size_t sz)40 void hex2binImpl(const char* s, uint8_t* b, size_t sz) {
41     for (; sz > 0; s += 2, ++b, --sz) {
42         *b = (hex2bin1(s[0]) << 4) | hex2bin1(s[1]);
43     }
44 }
45 
hex2bin(const std::string_view hex,std::vector<uint8_t> * bin)46 bool hex2bin(const std::string_view hex, std::vector<uint8_t>* bin) {
47     if (hex.size() & 1) {
48         return FAILURE_V(false, "%s", "odd length");
49     }
50 
51     const size_t sz = hex.size() / 2;
52     bin->resize(sz);
53     hex2binImpl(hex.data(), bin->data(), sz);
54     return true;
55 }
56 
bin2hex1(const unsigned x)57 char bin2hex1(const unsigned x) {
58     return (x < 10) ? char(x + '0') : char(x - 10 + 'A');
59 }
60 
bin2hexImpl(const uint8_t * b,char * s,size_t sz)61 void bin2hexImpl(const uint8_t* b, char* s, size_t sz) {
62     for (; sz > 0; s += 2, ++b, --sz) {
63         const unsigned bb = *b;
64         s[0] = bin2hex1(bb >> 4);
65         s[1] = bin2hex1(bb & 0xF);
66     }
67 }
68 
bin2hex(const uint8_t * b,const size_t sz)69 std::string bin2hex(const uint8_t* b, const size_t sz) {
70     std::string str(sz + sz, '?');
71     bin2hexImpl(b, str.data(), sz);
72     return str;
73 }
74 
base64encode(const void * const binaryData,const size_t binarySize)75 std::string base64encode(const void* const binaryData, const size_t binarySize) {
76     int size = ((binarySize + 2) / 3 * 4) + 1;  // `+1` is for the "trailing NUL"
77     std::string encoded(size, '?');
78     size = EVP_EncodeBlock(reinterpret_cast<uint8_t *>(encoded.data()),
79                            static_cast<const uint8_t*>(binaryData),
80                            binarySize);
81     encoded.resize(size);  // without "trailing NUL"
82     LOG_ALWAYS_FATAL_IF(size < 0);
83     return encoded;
84 }
85 
base64decode(const char * const encodedData,const size_t encodedSize)86 std::optional<std::vector<uint8_t>> base64decode(const char* const encodedData, const size_t encodedSize) {
87     if (encodedSize % 4) {
88         return std::nullopt;
89     }
90 
91     int size = encodedSize / 4 * 3;
92     std::vector<uint8_t> decoded(size);
93     size = EVP_DecodeBlock(decoded.data(),
94                            reinterpret_cast<const uint8_t*>(encodedData),
95                            encodedSize);
96     if (size < 0) {
97         return std::nullopt;
98     } else {
99         decoded.resize(size);
100         return decoded;
101     }
102 }
103 
104 }  // namespace implementation
105 }  // namespace radio
106 }  // namespace hardware
107 }  // namespace android
108 }  // namespace aidl
109