1 // Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <cstring> // memcpy 6 7 #include <base/stl_util.h> 8 #include <base/strings/string_number_conversions.h> 9 10 #include "brillo/secure_blob.h" 11 12 namespace brillo { 13 14 std::string BlobToString(const Blob& blob) { 15 return std::string(blob.begin(), blob.end()); 16 } 17 18 Blob BlobFromString(const std::string& bytes) { 19 return Blob(bytes.begin(), bytes.end()); 20 } 21 22 Blob CombineBlobs(const std::initializer_list<Blob>& blobs) { 23 size_t total_size = 0; 24 for (const auto& blob : blobs) 25 total_size += blob.size(); 26 Blob concatenation; 27 concatenation.reserve(total_size); 28 for (const auto& blob : blobs) 29 concatenation.insert(concatenation.end(), blob.begin(), blob.end()); 30 return concatenation; 31 } 32 33 SecureBlob::SecureBlob(const Blob& blob) 34 : SecureBlob(blob.begin(), blob.end()) {} 35 36 SecureBlob::SecureBlob(const std::string& data) 37 : SecureBlob(data.begin(), data.end()) {} 38 39 SecureBlob::~SecureBlob() { 40 clear(); 41 } 42 43 void SecureBlob::resize(size_type count) { 44 if (count < size()) { 45 SecureMemset(data() + count, 0, capacity() - count); 46 } 47 Blob::resize(count); 48 } 49 50 void SecureBlob::resize(size_type count, const value_type& value) { 51 if (count < size()) { 52 SecureMemset(data() + count, 0, capacity() - count); 53 } 54 Blob::resize(count, value); 55 } 56 57 void SecureBlob::clear() { 58 SecureMemset(data(), 0, capacity()); 59 Blob::clear(); 60 } 61 62 std::string SecureBlob::to_string() const { 63 return std::string(data(), data() + size()); 64 } 65 66 SecureBlob SecureBlob::Combine(const SecureBlob& blob1, 67 const SecureBlob& blob2) { 68 SecureBlob result; 69 result.reserve(blob1.size() + blob2.size()); 70 result.insert(result.end(), blob1.begin(), blob1.end()); 71 result.insert(result.end(), blob2.begin(), blob2.end()); 72 return result; 73 } 74 75 bool SecureBlob::HexStringToSecureBlob(const std::string& input, 76 SecureBlob* output) { 77 // TODO(jorgelo,crbug.com/728047): Consider not using an intermediate 78 // std::vector here at all. 79 std::vector<uint8_t> temp; 80 if (!base::HexStringToBytes(input, &temp)) { 81 output->clear(); 82 return false; 83 } 84 output->assign(temp.begin(), temp.end()); 85 SecureMemset(temp.data(), 0, temp.capacity()); 86 return true; 87 } 88 89 BRILLO_DISABLE_ASAN void* SecureMemset(void* v, int c, size_t n) { 90 volatile uint8_t* p = reinterpret_cast<volatile uint8_t*>(v); 91 while (n--) 92 *p++ = c; 93 return v; 94 } 95 96 int SecureMemcmp(const void* s1, const void* s2, size_t n) { 97 const uint8_t* us1 = reinterpret_cast<const uint8_t*>(s1); 98 const uint8_t* us2 = reinterpret_cast<const uint8_t*>(s2); 99 int result = 0; 100 101 if (0 == n) 102 return 1; 103 104 /* Code snippet without data-dependent branch due to 105 * Nate Lawson (nate (at) root.org) of Root Labs. */ 106 while (n--) 107 result |= *us1++ ^ *us2++; 108 109 return result != 0; 110 } 111 112 } // namespace brillo 113