Home | History | Annotate | Download | only in brillo
      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