blob: 4cfaa16bdf849e6a358b64102ccb9eeb2131b52f [file] [log] [blame]
// Copyright 2020 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "shill/crypto.h"
#include <string_view>
#include <utility>
#include <base/strings/string_util.h>
#include "shill/logging.h"
using std::string;
namespace shill {
namespace {
constexpr char kRot47Id[] = "rot47:";
string Rot47Encrypt(std::string_view plaintext) {
const int kRotSize = 94;
const int kRotHalf = kRotSize / 2;
const char kRotMin = '!';
const char kRotMax = kRotMin + kRotSize - 1;
string ciphertext;
ciphertext.reserve(plaintext.size());
for (auto ch : plaintext) {
if (kRotMin <= ch && ch <= kRotMax) {
int rot = ch + kRotHalf;
ch = (rot > kRotMax) ? rot - kRotSize : rot;
}
ciphertext.push_back(ch);
}
return ciphertext;
}
} // namespace
namespace Crypto {
string Encrypt(const string& plaintext) {
return string(kRot47Id) + Rot47Encrypt(plaintext);
}
base::Optional<string> Decrypt(const string& ciphertext) {
if (!base::StartsWith(ciphertext, kRot47Id, base::CompareCase::SENSITIVE)) {
LOG(ERROR) << "Cannot decrypt non-ROT47 ciphertext";
return base::nullopt;
}
std::string_view to_decrypt = ciphertext;
to_decrypt.remove_prefix(sizeof(kRot47Id) - 1);
// ROT47 is self-reciprocal.
return Rot47Encrypt(std::move(to_decrypt));
}
} // namespace Crypto
} // namespace shill