This repository was archived by the owner on Apr 17, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathcrypto.cc
More file actions
112 lines (98 loc) · 3.98 KB
/
Copy pathcrypto.cc
File metadata and controls
112 lines (98 loc) · 3.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "crypto.h"
#include "config.h"
#include "absl/status/status.h"
namespace cpu_check {
namespace {
constexpr unsigned char key[33] = "0123456789abcdef0123456789abcdef";
}; // namespace
absl::Status Crypto::Encrypt(const MalignBuffer &plain_text,
MalignBuffer *cipher_text, CryptoPurse *purse) {
memset(purse->i_vec, 0, sizeof(purse->i_vec));
memcpy(purse->i_vec, plain_text.data(),
std::min(plain_text.size(), sizeof(purse->i_vec)));
int enc_len = 0;
int enc_unused_len = 0;
EVP_CIPHER_CTX *cipher_ctx = EVP_CIPHER_CTX_new();
EVP_CipherInit_ex(cipher_ctx, EVP_aes_256_gcm(), NULL, key, purse->i_vec, 1);
if (EVP_CipherUpdate(
cipher_ctx,
reinterpret_cast<unsigned char *>(cipher_text->data()),
&enc_len, reinterpret_cast<const unsigned char *>(plain_text.data()),
plain_text.size()) != 1) {
return ReturnError("EVP_CipherUpdate", cipher_ctx);
}
if (EVP_CipherFinal_ex(cipher_ctx, nullptr, &enc_unused_len) != 1) {
return ReturnError("encrypt_EVP_CipherFinal_ex", cipher_ctx);
}
enc_len += enc_unused_len;
if (enc_len != (int)cipher_text->size()) {
return ReturnError("encrypt_length_mismatch", cipher_ctx);
}
if (EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_GCM_GET_TAG,
sizeof(purse->gmac_tag), purse->gmac_tag) != 1) {
return ReturnError("EVP_CTRL_GCM_GET_TAG", cipher_ctx);
}
EVP_CIPHER_CTX_free(cipher_ctx);
return absl::OkStatus();
}
absl::Status Crypto::Decrypt(const MalignBuffer &cipher_text,
const CryptoPurse &purse,
MalignBuffer *plain_text) {
int dec_len = 0;
int dec_extra_len = 0;
EVP_CIPHER_CTX *cipher_ctx = EVP_CIPHER_CTX_new();
EVP_CipherInit_ex(cipher_ctx, EVP_aes_256_gcm(), NULL, key, purse.i_vec, 0);
// Make a non-const copy of gmac_tag because that's what EVP_CIPHER_CTX_ctrl
// requires, even though it won't be modified in this use.
unsigned char copied_tag[sizeof(purse.gmac_tag)];
memcpy(copied_tag, purse.gmac_tag, sizeof(purse.gmac_tag));
if (EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_GCM_SET_TAG, sizeof(copied_tag),
reinterpret_cast<void *>(copied_tag)) != 1) {
return ReturnError("EVP_CTRL_GCM_SET_TAG", cipher_ctx);
}
if (EVP_CipherUpdate(
cipher_ctx, reinterpret_cast<unsigned char *>(plain_text->data()),
&dec_len, reinterpret_cast<const unsigned char *>(cipher_text.data()),
cipher_text.size()) != 1) {
return ReturnError("Decryption", cipher_ctx);
}
if (EVP_CipherFinal_ex(
cipher_ctx,
reinterpret_cast<unsigned char *>(plain_text->data() + dec_len),
&dec_extra_len) != 1) {
return ReturnError("decrypt_EVP_CipherFinal_ex", cipher_ctx);
}
dec_len += dec_extra_len;
if (dec_len != (int)plain_text->size()) {
return ReturnError("decrypt_length_mismatch", cipher_ctx);
}
EVP_CIPHER_CTX_free(cipher_ctx);
return absl::OkStatus();
}
absl::Status Crypto::SelfTest() {
#ifdef USE_BORINGSSL
if (BORINGSSL_self_test() == 0) {
return absl::Status(absl::StatusCode::kInternal, "BORINGSSL_self_test");
}
#endif
return absl::OkStatus();
}
absl::Status Crypto::ReturnError(absl::string_view message,
EVP_CIPHER_CTX *cipher_ctx) {
EVP_CIPHER_CTX_free(cipher_ctx);
return absl::Status(absl::StatusCode::kInternal, message);
}
}; // namespace cpu_check