parent
e8f69a734a
commit
d5fb4a8763
@ -0,0 +1,131 @@ |
||||
# Contributor Covenant Code of Conduct |
||||
|
||||
## Our Pledge |
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our |
||||
community a harassment-free experience for everyone, regardless of age, body |
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender |
||||
identity and expression, level of experience, education, socio-economic status, |
||||
nationality, personal appearance, race, caste, color, religion, or sexual |
||||
identity and orientation. |
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming, |
||||
diverse, inclusive, and healthy community. |
||||
|
||||
## Our Standards |
||||
|
||||
Examples of behavior that contributes to a positive environment for our |
||||
community include: |
||||
|
||||
* Demonstrating empathy and kindness toward other people |
||||
* Being respectful of differing opinions, viewpoints, and experiences |
||||
* Giving and gracefully accepting constructive feedback |
||||
* Accepting responsibility and apologizing to those affected by our mistakes, |
||||
and learning from the experience |
||||
* Focusing on what is best not just for us as individuals, but for the overall |
||||
community |
||||
|
||||
Examples of unacceptable behavior include: |
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or advances of |
||||
any kind |
||||
* Trolling, insulting or derogatory comments, and personal or political attacks |
||||
* Public or private harassment |
||||
* Publishing others' private information, such as a physical or email address, |
||||
without their explicit permission |
||||
* Other conduct which could reasonably be considered inappropriate in a |
||||
professional setting |
||||
|
||||
## Enforcement Responsibilities |
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of |
||||
acceptable behavior and will take appropriate and fair corrective action in |
||||
response to any behavior that they deem inappropriate, threatening, offensive, |
||||
or harmful. |
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject |
||||
comments, commits, code, wiki edits, issues, and other contributions that are |
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation |
||||
decisions when appropriate. |
||||
|
||||
## Scope |
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when |
||||
an individual is officially representing the community in public spaces. |
||||
Examples of representing our community include using an official e-mail address, |
||||
posting via an official social media account, or acting as an appointed |
||||
representative at an online or offline event. |
||||
|
||||
## Enforcement |
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be |
||||
reported to the community leaders responsible for enforcement at |
||||
CommunityCodeOfConduct AT intel DOT com. |
||||
All complaints will be reviewed and investigated promptly and fairly. |
||||
|
||||
All community leaders are obligated to respect the privacy and security of the |
||||
reporter of any incident. |
||||
|
||||
## Enforcement Guidelines |
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining |
||||
the consequences for any action they deem in violation of this Code of Conduct: |
||||
|
||||
### 1. Correction |
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed |
||||
unprofessional or unwelcome in the community. |
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing |
||||
clarity around the nature of the violation and an explanation of why the |
||||
behavior was inappropriate. A public apology may be requested. |
||||
|
||||
### 2. Warning |
||||
|
||||
**Community Impact**: A violation through a single incident or series of |
||||
actions. |
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No |
||||
interaction with the people involved, including unsolicited interaction with |
||||
those enforcing the Code of Conduct, for a specified period of time. This |
||||
includes avoiding interactions in community spaces as well as external channels |
||||
like social media. Violating these terms may lead to a temporary or permanent |
||||
ban. |
||||
|
||||
### 3. Temporary Ban |
||||
|
||||
**Community Impact**: A serious violation of community standards, including |
||||
sustained inappropriate behavior. |
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public |
||||
communication with the community for a specified period of time. No public or |
||||
private interaction with the people involved, including unsolicited interaction |
||||
with those enforcing the Code of Conduct, is allowed during this period. |
||||
Violating these terms may lead to a permanent ban. |
||||
|
||||
### 4. Permanent Ban |
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community |
||||
standards, including sustained inappropriate behavior, harassment of an |
||||
individual, or aggression toward or disparagement of classes of individuals. |
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within the |
||||
community. |
||||
|
||||
## Attribution |
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], |
||||
version 2.1, available at |
||||
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. |
||||
|
||||
Community Impact Guidelines were inspired by |
||||
[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. |
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at |
||||
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at |
||||
[https://www.contributor-covenant.org/translations][translations]. |
||||
|
||||
[homepage]: https://www.contributor-covenant.org |
||||
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html |
||||
[Mozilla CoC]: https://github.com/mozilla/diversity |
||||
[FAQ]: https://www.contributor-covenant.org/faq |
@ -0,0 +1,57 @@ |
||||
# Contributing |
||||
|
||||
### License |
||||
|
||||
Intel® Integrated Performance Primitives Cryptography Plugin for RocksDB* Storage Engine is licensed under the terms in [Apache License](LICENSE). By contributing to the project, you agree to the license and copyright terms therein and release your contribution under these terms. |
||||
|
||||
### Sign your work |
||||
|
||||
Please use the sign-off line at the end of the patch. Your signature certifies that you wrote the patch or otherwise have the right to pass it on as an open-source patch. The rules are pretty simple: if you can certify |
||||
the below (from [developercertificate.org](http://developercertificate.org/)): |
||||
|
||||
``` |
||||
Developer Certificate of Origin |
||||
Version 1.1 |
||||
|
||||
Copyright (C) 2004, 2006 The Linux Foundation and its contributors. |
||||
660 York Street, Suite 102, |
||||
San Francisco, CA 94110 USA |
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this |
||||
license document, but changing it is not allowed. |
||||
|
||||
Developer's Certificate of Origin 1.1 |
||||
|
||||
By making a contribution to this project, I certify that: |
||||
|
||||
(a) The contribution was created in whole or in part by me and I |
||||
have the right to submit it under the open source license |
||||
indicated in the file; or |
||||
|
||||
(b) The contribution is based upon previous work that, to the best |
||||
of my knowledge, is covered under an appropriate open source |
||||
license and I have the right under that license to submit that |
||||
work with modifications, whether created in whole or in part |
||||
by me, under the same open source license (unless I am |
||||
permitted to submit under a different license), as indicated |
||||
in the file; or |
||||
|
||||
(c) The contribution was provided directly to me by some other |
||||
person who certified (a), (b) or (c) and I have not modified |
||||
it. |
||||
|
||||
(d) I understand and agree that this project and the contribution |
||||
are public and that a record of the contribution (including all |
||||
personal information I submit with it, including my sign-off) is |
||||
maintained indefinitely and may be redistributed consistent with |
||||
this project or the open source license(s) involved. |
||||
``` |
||||
|
||||
Then you just add a line to every git commit message: |
||||
|
||||
Signed-off-by: Joe Smith <joe.smith@email.com> |
||||
|
||||
Use your real name (sorry, no pseudonyms or anonymous contributions.) |
||||
|
||||
If you set your `user.name` and `user.email` git configs, you can sign your |
||||
commit automatically with `git commit -s`. |
@ -0,0 +1,201 @@ |
||||
Apache License |
||||
Version 2.0, January 2004 |
||||
http://www.apache.org/licenses/ |
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |
||||
|
||||
1. Definitions. |
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, |
||||
and distribution as defined by Sections 1 through 9 of this document. |
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by |
||||
the copyright owner that is granting the License. |
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all |
||||
other entities that control, are controlled by, or are under common |
||||
control with that entity. For the purposes of this definition, |
||||
"control" means (i) the power, direct or indirect, to cause the |
||||
direction or management of such entity, whether by contract or |
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the |
||||
outstanding shares, or (iii) beneficial ownership of such entity. |
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity |
||||
exercising permissions granted by this License. |
||||
|
||||
"Source" form shall mean the preferred form for making modifications, |
||||
including but not limited to software source code, documentation |
||||
source, and configuration files. |
||||
|
||||
"Object" form shall mean any form resulting from mechanical |
||||
transformation or translation of a Source form, including but |
||||
not limited to compiled object code, generated documentation, |
||||
and conversions to other media types. |
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or |
||||
Object form, made available under the License, as indicated by a |
||||
copyright notice that is included in or attached to the work |
||||
(an example is provided in the Appendix below). |
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object |
||||
form, that is based on (or derived from) the Work and for which the |
||||
editorial revisions, annotations, elaborations, or other modifications |
||||
represent, as a whole, an original work of authorship. For the purposes |
||||
of this License, Derivative Works shall not include works that remain |
||||
separable from, or merely link (or bind by name) to the interfaces of, |
||||
the Work and Derivative Works thereof. |
||||
|
||||
"Contribution" shall mean any work of authorship, including |
||||
the original version of the Work and any modifications or additions |
||||
to that Work or Derivative Works thereof, that is intentionally |
||||
submitted to Licensor for inclusion in the Work by the copyright owner |
||||
or by an individual or Legal Entity authorized to submit on behalf of |
||||
the copyright owner. For the purposes of this definition, "submitted" |
||||
means any form of electronic, verbal, or written communication sent |
||||
to the Licensor or its representatives, including but not limited to |
||||
communication on electronic mailing lists, source code control systems, |
||||
and issue tracking systems that are managed by, or on behalf of, the |
||||
Licensor for the purpose of discussing and improving the Work, but |
||||
excluding communication that is conspicuously marked or otherwise |
||||
designated in writing by the copyright owner as "Not a Contribution." |
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity |
||||
on behalf of whom a Contribution has been received by Licensor and |
||||
subsequently incorporated within the Work. |
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of |
||||
this License, each Contributor hereby grants to You a perpetual, |
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||
copyright license to reproduce, prepare Derivative Works of, |
||||
publicly display, publicly perform, sublicense, and distribute the |
||||
Work and such Derivative Works in Source or Object form. |
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of |
||||
this License, each Contributor hereby grants to You a perpetual, |
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||
(except as stated in this section) patent license to make, have made, |
||||
use, offer to sell, sell, import, and otherwise transfer the Work, |
||||
where such license applies only to those patent claims licensable |
||||
by such Contributor that are necessarily infringed by their |
||||
Contribution(s) alone or by combination of their Contribution(s) |
||||
with the Work to which such Contribution(s) was submitted. If You |
||||
institute patent litigation against any entity (including a |
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work |
||||
or a Contribution incorporated within the Work constitutes direct |
||||
or contributory patent infringement, then any patent licenses |
||||
granted to You under this License for that Work shall terminate |
||||
as of the date such litigation is filed. |
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the |
||||
Work or Derivative Works thereof in any medium, with or without |
||||
modifications, and in Source or Object form, provided that You |
||||
meet the following conditions: |
||||
|
||||
(a) You must give any other recipients of the Work or |
||||
Derivative Works a copy of this License; and |
||||
|
||||
(b) You must cause any modified files to carry prominent notices |
||||
stating that You changed the files; and |
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works |
||||
that You distribute, all copyright, patent, trademark, and |
||||
attribution notices from the Source form of the Work, |
||||
excluding those notices that do not pertain to any part of |
||||
the Derivative Works; and |
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its |
||||
distribution, then any Derivative Works that You distribute must |
||||
include a readable copy of the attribution notices contained |
||||
within such NOTICE file, excluding those notices that do not |
||||
pertain to any part of the Derivative Works, in at least one |
||||
of the following places: within a NOTICE text file distributed |
||||
as part of the Derivative Works; within the Source form or |
||||
documentation, if provided along with the Derivative Works; or, |
||||
within a display generated by the Derivative Works, if and |
||||
wherever such third-party notices normally appear. The contents |
||||
of the NOTICE file are for informational purposes only and |
||||
do not modify the License. You may add Your own attribution |
||||
notices within Derivative Works that You distribute, alongside |
||||
or as an addendum to the NOTICE text from the Work, provided |
||||
that such additional attribution notices cannot be construed |
||||
as modifying the License. |
||||
|
||||
You may add Your own copyright statement to Your modifications and |
||||
may provide additional or different license terms and conditions |
||||
for use, reproduction, or distribution of Your modifications, or |
||||
for any such Derivative Works as a whole, provided Your use, |
||||
reproduction, and distribution of the Work otherwise complies with |
||||
the conditions stated in this License. |
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, |
||||
any Contribution intentionally submitted for inclusion in the Work |
||||
by You to the Licensor shall be under the terms and conditions of |
||||
this License, without any additional terms or conditions. |
||||
Notwithstanding the above, nothing herein shall supersede or modify |
||||
the terms of any separate license agreement you may have executed |
||||
with Licensor regarding such Contributions. |
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade |
||||
names, trademarks, service marks, or product names of the Licensor, |
||||
except as required for reasonable and customary use in describing the |
||||
origin of the Work and reproducing the content of the NOTICE file. |
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or |
||||
agreed to in writing, Licensor provides the Work (and each |
||||
Contributor provides its Contributions) on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
||||
implied, including, without limitation, any warranties or conditions |
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |
||||
PARTICULAR PURPOSE. You are solely responsible for determining the |
||||
appropriateness of using or redistributing the Work and assume any |
||||
risks associated with Your exercise of permissions under this License. |
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, |
||||
whether in tort (including negligence), contract, or otherwise, |
||||
unless required by applicable law (such as deliberate and grossly |
||||
negligent acts) or agreed to in writing, shall any Contributor be |
||||
liable to You for damages, including any direct, indirect, special, |
||||
incidental, or consequential damages of any character arising as a |
||||
result of this License or out of the use or inability to use the |
||||
Work (including but not limited to damages for loss of goodwill, |
||||
work stoppage, computer failure or malfunction, or any and all |
||||
other commercial damages or losses), even if such Contributor |
||||
has been advised of the possibility of such damages. |
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing |
||||
the Work or Derivative Works thereof, You may choose to offer, |
||||
and charge a fee for, acceptance of support, warranty, indemnity, |
||||
or other liability obligations and/or rights consistent with this |
||||
License. However, in accepting such obligations, You may act only |
||||
on Your own behalf and on Your sole responsibility, not on behalf |
||||
of any other Contributor, and only if You agree to indemnify, |
||||
defend, and hold each Contributor harmless for any liability |
||||
incurred by, or claims asserted against, such Contributor by reason |
||||
of your accepting any such warranty or additional liability. |
||||
|
||||
END OF TERMS AND CONDITIONS |
||||
|
||||
APPENDIX: How to apply the Apache License to your work. |
||||
|
||||
To apply the Apache License to your work, attach the following |
||||
boilerplate notice, with the fields enclosed by brackets "{}" |
||||
replaced with your own identifying information. (Don't include |
||||
the brackets!) The text should be enclosed in the appropriate |
||||
comment syntax for the file format. We also recommend that a |
||||
file or class name and description of purpose be included on the |
||||
same "printed page" as the copyright notice for easier |
||||
identification within third-party archives. |
||||
|
||||
Copyright {yyyy} {name of copyright owner} |
||||
|
||||
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. |
@ -0,0 +1,62 @@ |
||||
# Intel® Integrated Performance Primitives Cryptography Plugin for RocksDB* Storage Engine |
||||
|
||||
`ippcp` is an encryption provider for RocksDB that is based on Intel's Integrated Performance Primitives for Cryptography (IPPCP). IPPCP is a lightweight cryptography library that is highly optimized for various Intel CPUs. It's used here to provide AES-128/192/256 encryption, with a CTR mode of operation, for RocksDB. |
||||
|
||||
## Prerequisite |
||||
|
||||
There is a dependency on ipp cryptograhy library (ippcp) which needs to be installed. Please refer below link for installtion. |
||||
https://www.intel.com/content/www/us/en/develop/documentation/get-started-with-ipp-crypto-for-oneapi-linux/top.html |
||||
|
||||
Once Installed source /opt/intel/oneapi/ippcp/latest/env/var.sh |
||||
|
||||
|
||||
## Build |
||||
|
||||
The code first needs to be linked under RocksDB's "plugin/" directory. In your RocksDB directory, run: |
||||
|
||||
``` |
||||
$ pushd ./plugin/ |
||||
$ git clone https://github.com/intel/ippcp-plugin-rocksdb.git ippcp |
||||
``` |
||||
|
||||
Next, we can build and install RocksDB with this plugin as follows: |
||||
|
||||
``` |
||||
$ popd |
||||
$ make clean && ROCKSDB_PLUGINS=ippcp make -j48 release |
||||
``` |
||||
|
||||
## Testing |
||||
|
||||
* Install ipp cryptograhy library (ippcp) as described in the previous section. |
||||
* Install https://github.com/google/googletest |
||||
* Build RocksDB as a shared library |
||||
|
||||
``` |
||||
LIB_MODE=shared make -j release |
||||
|
||||
``` |
||||
|
||||
* Go to the tests directory of ippcp plugin and build as mentioned below: |
||||
|
||||
``` |
||||
cd plugin/ippcp/tests/ |
||||
mkdir build |
||||
cd build |
||||
cmake -DROCKSDB_PATH=<rocksdb_install_directory> -DIPPCRYPTOROOT=<ippcp_install_directory> .. |
||||
make run |
||||
|
||||
``` |
||||
## Tool usage |
||||
|
||||
For RocksDB binaries (such as the `db_bench` we built above), the plugin can be enabled through configuration. `db_bench` in particular takes a `--fs_uri` where we can specify "dedupfs" , which is the name registered by this plugin. Example usage: |
||||
|
||||
``` |
||||
$ ./db_bench --benchmarks=fillseq --env_uri=ippcp_db_bench_env --compression_type=none |
||||
``` |
||||
|
||||
## Application usage |
||||
|
||||
The plugin's interface is also exposed to applications, which can enable it either through configuration or through code. Example available under the "examples/" directory. |
||||
|
||||
``` |
@ -0,0 +1,12 @@ |
||||
include ../../../make_config.mk |
||||
|
||||
PLATFORM_LDFLAGS += -lrocksdb -lippcp -L../../.. -L../../../../ipp-crypto/_build/.build/RELEASE/lib
|
||||
.PHONY: clean |
||||
|
||||
all: ippcp_example |
||||
|
||||
ippcp_example: ippcp_example.cc |
||||
$(CXX) $(CXXFLAGS) $@.cc -o$@ -I../../../include -O2 $(PLATFORM_LDFLAGS) $(PLATFORM_CXXFLAGS) -I../../../../ipp-crypto/_build/.build/RELEASE/include
|
||||
|
||||
clean: |
||||
rm -rf ./ippcp_example
|
Binary file not shown.
@ -0,0 +1,68 @@ |
||||
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
||||
// Copyright (c) 2020 Intel Corporation
|
||||
// This source code is licensed under both the GPLv2 (found in the
|
||||
// COPYING file in the root directory) and Apache 2.0 License
|
||||
// (found in the LICENSE.Apache file in the root directory).
|
||||
|
||||
#include <rocksdb/db.h> |
||||
#include <rocksdb/env_encryption.h> |
||||
#include <rocksdb/options.h> |
||||
#include <rocksdb/slice.h> |
||||
#include <rocksdb/utilities/options_util.h> |
||||
#include <rocksdb/utilities/object_registry.h> |
||||
|
||||
#include <string> |
||||
|
||||
#include "../ippcp_provider.h" |
||||
|
||||
using namespace ROCKSDB_NAMESPACE; |
||||
|
||||
std::string kDBPath = "/tmp/ipp_aes_example"; |
||||
|
||||
int main() { |
||||
DB* db; |
||||
Options options; |
||||
options.create_if_missing = true; |
||||
|
||||
std::shared_ptr<EncryptionProvider> provider; |
||||
Status status = EncryptionProvider::CreateFromString( |
||||
ConfigOptions(), IppcpProvider::kName(), &provider); |
||||
assert(status.ok()); |
||||
|
||||
status = |
||||
provider->AddCipher("", "a6d2ae2816157e2b3c4fcf098815f7xb", 32, false); |
||||
assert(status.ok()); |
||||
|
||||
options.env = NewEncryptedEnv(Env::Default(), provider); |
||||
|
||||
status = DB::Open(options, kDBPath, &db); |
||||
assert(status.ok()); |
||||
|
||||
setbuf(stdout, NULL); |
||||
printf("writing 1M records..."); |
||||
WriteOptions w_opts; |
||||
for (int i = 0; i < 1000000; ++i) { |
||||
status = db->Put(w_opts, std::to_string(i), std::to_string(i * i)); |
||||
assert(status.ok()); |
||||
} |
||||
db->Flush(FlushOptions()); |
||||
printf("done.\n"); |
||||
|
||||
printf("reading 1M records..."); |
||||
std::string value; |
||||
ReadOptions r_opts; |
||||
for (int i = 0; i < 1000000; ++i) { |
||||
status = db->Get(r_opts, std::to_string(i), &value); |
||||
assert(status.ok()); |
||||
assert(value == std::to_string(i * i)); |
||||
} |
||||
printf("done.\n"); |
||||
|
||||
// Close database
|
||||
status = db->Close(); |
||||
assert(status.ok()); |
||||
//status = DestroyDB(kDBPath, options);
|
||||
//assert(status.ok());
|
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,12 @@ |
||||
include ../../../make_config.mk |
||||
|
||||
PLATFORM_LDFLAGS += -lrocksdb -lippcp -L../../.. -L../../../../ipp-crypto/_build/.build/RELEASE/lib
|
||||
.PHONY: clean |
||||
|
||||
all: ippcp_example |
||||
|
||||
ippcp_example: ippcp_example.cc |
||||
$(CXX) $(CXXFLAGS) $@.cc -o$@ -I../../../include -O2 $(PLATFORM_LDFLAGS) $(PLATFORM_CXXFLAGS) -I../../../../ipp-crypto/_build/.build/RELEASE/include
|
||||
|
||||
clean: |
||||
rm -rf ./ippcp_example
|
Binary file not shown.
@ -0,0 +1,66 @@ |
||||
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
||||
// Copyright (c) 2020 Intel Corporation
|
||||
// This source code is licensed under both the GPLv2 (found in the
|
||||
// COPYING file in the root directory) and Apache 2.0 License
|
||||
// (found in the LICENSE.Apache file in the root directory).
|
||||
|
||||
#include <rocksdb/db.h> |
||||
#include <rocksdb/env.h> |
||||
#include <rocksdb/options.h> |
||||
#include <rocksdb/slice.h> |
||||
#include <rocksdb/utilities/options_util.h> |
||||
#include <rocksdb/utilities/object_registry.h> |
||||
|
||||
#include <string> |
||||
|
||||
#include "../ippcp_provider.h" |
||||
|
||||
using namespace ROCKSDB_NAMESPACE; |
||||
|
||||
std::string kDBPath = "/tmp/ipp_aes_example2"; |
||||
|
||||
int main() { |
||||
DB* db; |
||||
Options options; |
||||
options.create_if_missing = true; |
||||
|
||||
// std::shared_ptr<EncryptionProvider> provider;
|
||||
// Status status = EncryptionProvider::CreateFromString(
|
||||
// ConfigOptions(), IppcpProvider::kName(), &provider);
|
||||
// assert(status.ok());
|
||||
|
||||
// status =
|
||||
// provider->AddCipher("", "a6d2ae2816157e2b3c4fcf098815f7xb", 32, false);
|
||||
// assert(status.ok());
|
||||
|
||||
Status status = DB::Open(options, kDBPath, &db); |
||||
assert(status.ok()); |
||||
|
||||
setbuf(stdout, NULL); |
||||
printf("writing 1M records..."); |
||||
WriteOptions w_opts; |
||||
for (int i = 0; i < 1000000; ++i) { |
||||
status = db->Put(w_opts, std::to_string(i), std::to_string(i * i)); |
||||
assert(status.ok()); |
||||
} |
||||
db->Flush(FlushOptions()); |
||||
printf("done.\n"); |
||||
|
||||
printf("reading 1M records..."); |
||||
std::string value; |
||||
ReadOptions r_opts; |
||||
for (int i = 0; i < 1000000; ++i) { |
||||
status = db->Get(r_opts, std::to_string(i), &value); |
||||
assert(status.ok()); |
||||
assert(value == std::to_string(i * i)); |
||||
} |
||||
printf("done.\n"); |
||||
|
||||
// Close database
|
||||
status = db->Close(); |
||||
assert(status.ok()); |
||||
//status = DestroyDB(kDBPath, options);
|
||||
//assert(status.ok());
|
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,4 @@ |
||||
ippcp_SOURCES = ippcp_provider.cc
|
||||
ippcp_HEADERS = ippcp_provider.h
|
||||
ippcp_LDFLAGS = -lippcp
|
||||
ippcp_CXXFLAGS = -I../ipp-crypto/_build/.build/RELEASE/include
|
@ -0,0 +1,32 @@ |
||||
// Copyright (c) 2021-present, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under both the GPLv2 (found in the
|
||||
// COPYING file in the root directory) and Apache 2.0 License
|
||||
// (found in the LICENSE.Apache file in the root directory).
|
||||
|
||||
#include <rocksdb/utilities/object_registry.h> |
||||
|
||||
#include "ippcp_provider.h" |
||||
|
||||
namespace ROCKSDB_NAMESPACE { |
||||
|
||||
#ifndef ROCKSDB_LITE |
||||
|
||||
extern "C" FactoryFunc<Env> ippcp_db_bench_env; |
||||
|
||||
// Registers a sample ippcp encrypted environment that can be used in db_bench
|
||||
// by passing --env_uri=ippcp_db_bench_env parameter.
|
||||
|
||||
FactoryFunc<Env> ippcp_db_bench_env = ObjectLibrary::Default()->AddFactory<Env>( |
||||
"ippcp_db_bench_env", |
||||
[](const std::string& /* uri */, std::unique_ptr<Env>* f, |
||||
std::string* /* errmsg */) { |
||||
auto provider = |
||||
std::shared_ptr<EncryptionProvider>(IppcpProvider::CreateProvider()); |
||||
provider->AddCipher("", "a6d2ae2816157e2b3c4fcf098815f7xb", 32, false); |
||||
*f = std::unique_ptr<Env>(NewEncryptedEnv(Env::Default(), provider)); |
||||
return f->get(); |
||||
}); |
||||
|
||||
#endif // ROCKSDB_LITE
|
||||
|
||||
} // namespace ROCKSDB_NAMESPACE
|
@ -0,0 +1,250 @@ |
||||
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
||||
// Copyright (c) 2020 Intel Corporation
|
||||
// This source code is licensed under both the GPLv2 (found in the
|
||||
// COPYING file in the root directory) and Apache 2.0 License
|
||||
// (found in the LICENSE.Apache file in the root directory).
|
||||
|
||||
#ifndef ROCKSDB_LITE |
||||
|
||||
#include "ippcp_provider.h" |
||||
|
||||
#include <emmintrin.h> |
||||
#include <ippcp.h> |
||||
#include <rocksdb/utilities/object_registry.h> |
||||
#include "rocksdb/utilities/customizable_util.h" |
||||
#include <memory> |
||||
|
||||
#endif |
||||
|
||||
namespace ROCKSDB_NAMESPACE { |
||||
|
||||
#ifndef ROCKSDB_LITE |
||||
|
||||
|
||||
static void RegisterEncryptionAES() { |
||||
static std::once_flag once; |
||||
std::call_once(once, [&]() { |
||||
|
||||
ObjectLibrary::Default()->AddFactory<EncryptionProvider>( |
||||
IppcpProvider::kName(), |
||||
[](const std::string& /* uri */, std::unique_ptr<EncryptionProvider>* f, |
||||
std::string* /* errmsg */) { |
||||
*f = IppcpProvider::CreateProvider(); |
||||
return f->get(); |
||||
}); |
||||
|
||||
}); |
||||
} |
||||
|
||||
Status EncryptionProvider::CreateFromString( |
||||
const ConfigOptions& config_options, const std::string& value, |
||||
std::shared_ptr<EncryptionProvider>* result) { |
||||
RegisterEncryptionAES(); |
||||
return LoadSharedObject<EncryptionProvider>(config_options, value, result); |
||||
} |
||||
|
||||
// extern "C" FactoryFunc<EncryptionProvider> ippcp_reg;
|
||||
|
||||
// FactoryFunc<EncryptionProvider> ippcp_reg =
|
||||
// ObjectLibrary::Default()->AddFactory<EncryptionProvider>(
|
||||
// IppcpProvider::kName(),
|
||||
// [](const std::string& /* uri */, std::unique_ptr<EncryptionProvider>* f,
|
||||
// std::string* /* errmsg */) {
|
||||
// *f = IppcpProvider::CreateProvider();
|
||||
// return f->get();
|
||||
// });
|
||||
|
||||
// IppcpCipherStream implements BlockAccessCipherStream using AES block
|
||||
// cipher and a CTR mode of operation.
|
||||
//
|
||||
// Since ipp-crypto can handle block sizes larger than kBlockSize (16 bytes for
|
||||
// AES) by chopping them internally into KBlockSize bytes, there is no need to
|
||||
// support the EncryptBlock and DecryptBlock member functions (and they will
|
||||
// never be called).
|
||||
//
|
||||
// See https://github.com/intel/ipp-crypto#documentation
|
||||
class IppcpCipherStream : public BlockAccessCipherStream { |
||||
public: |
||||
static constexpr size_t kBlockSize = 16; // in bytes
|
||||
static constexpr size_t kCounterLen = 64; // in bits
|
||||
|
||||
IppcpCipherStream(IppsAESSpec* aes_ctx, const char* init_vector); |
||||
|
||||
virtual Status Encrypt(uint64_t fileOffset, char* data, |
||||
size_t dataSize) override; |
||||
virtual Status Decrypt(uint64_t fileOffset, char* data, |
||||
size_t dataSize) override; |
||||
virtual size_t BlockSize() override { return kBlockSize; } |
||||
|
||||
protected: |
||||
// These functions are not needed and will never be called!
|
||||
virtual void AllocateScratch(std::string&) override {} |
||||
virtual Status EncryptBlock(uint64_t, char*, char*) override { |
||||
return Status::NotSupported("Operation not supported."); |
||||
} |
||||
virtual Status DecryptBlock(uint64_t, char*, char*) override { |
||||
return Status::NotSupported("Operation not supported."); |
||||
} |
||||
|
||||
private: |
||||
IppsAESSpec* aes_ctx_; |
||||
__m128i init_vector_; |
||||
}; |
||||
|
||||
IppcpCipherStream::IppcpCipherStream(IppsAESSpec* aes_ctx, |
||||
const char* init_vector) |
||||
: aes_ctx_(aes_ctx) { |
||||
init_vector_ = _mm_loadu_si128((__m128i*)init_vector); |
||||
} |
||||
|
||||
Status IppcpCipherStream::Encrypt(uint64_t fileOffset, char* data, |
||||
size_t dataSize) { |
||||
if (dataSize == 0) return Status::OK(); |
||||
|
||||
size_t index = fileOffset / kBlockSize; |
||||
size_t offset = fileOffset % kBlockSize; |
||||
|
||||
Ipp8u ctr_block[kBlockSize]; |
||||
|
||||
// evaluate the counter block from the block index
|
||||
__m128i counter = _mm_add_epi64(init_vector_, _mm_cvtsi64_si128(index)); |
||||
Ipp8u* ptr_counter = (Ipp8u*)&counter; |
||||
for (size_t i = 0; i < kBlockSize; ++i) |
||||
ctr_block[i] = ptr_counter[kBlockSize - 1 - i]; |
||||
|
||||
IppStatus ipp_status = ippStsNoErr; |
||||
|
||||
//- If offset is != 0, that means we would have first encrypt a partial block at the
|
||||
//beginning of the offset. That requires us to take the block index at that position and
|
||||
//manually do the xor operation – first we encrypt a block (called zero_block), and then
|
||||
//xor it starting at the offset.
|
||||
//Once that block is encrypted, we may exit (if the dataSize is less than kBlockSize) or
|
||||
//let ippcrypto start encrypting beginning a kBlockSize aligned offset
|
||||
//kCounterLen is 64 bits same as index size so that 64 bits are incremented
|
||||
// and counter stream generated by ipp and above match
|
||||
// https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf
|
||||
|
||||
if (offset == 0) { |
||||
ipp_status = ippsAESEncryptCTR((Ipp8u*)(data), (Ipp8u*)data, static_cast<int>(dataSize), |
||||
aes_ctx_, ctr_block, kCounterLen); |
||||
} else { |
||||
Ipp8u zero_block[kBlockSize]{0}; |
||||
ipp_status = ippsAESEncryptCTR(zero_block, zero_block, kBlockSize, aes_ctx_, |
||||
ctr_block, kCounterLen); |
||||
if (ipp_status != ippStsNoErr) |
||||
return Status::Aborted(ippcpGetStatusString(ipp_status)); |
||||
|
||||
size_t n = std::min(kBlockSize - offset, dataSize); |
||||
for (size_t i = 0; i < n; ++i) data[i] ^= zero_block[offset + i]; |
||||
memset(zero_block, 0, kBlockSize); |
||||
|
||||
n = kBlockSize - offset; |
||||
if (dataSize > n) { |
||||
Ipp8u* ptr = (Ipp8u*)(data + n); |
||||
ipp_status = ippsAESEncryptCTR(ptr, ptr, static_cast<int>(dataSize - n), aes_ctx_, |
||||
ctr_block, kCounterLen); |
||||
} |
||||
} |
||||
if (ipp_status == ippStsNoErr) return Status::OK(); |
||||
|
||||
return Status::Aborted(ippcpGetStatusString(ipp_status)); |
||||
} |
||||
|
||||
Status IppcpCipherStream::Decrypt(uint64_t fileOffset, char* data, |
||||
size_t dataSize) { |
||||
// Decryption is implemented as encryption in CTR mode of operation
|
||||
return Encrypt(fileOffset, data, dataSize); |
||||
} |
||||
|
||||
std::unique_ptr<EncryptionProvider> IppcpProvider::CreateProvider() { |
||||
return std::unique_ptr<EncryptionProvider>(new IppcpProvider); |
||||
} |
||||
|
||||
Status IppcpProvider::AddCipher(const std::string& /*descriptor*/, |
||||
const char* cipher, size_t len, |
||||
bool /*for_write*/) { |
||||
// We currently don't support more than one encryption key
|
||||
if (aes_ctx_ != nullptr) { |
||||
return Status::InvalidArgument("Multiple encryption keys not supported."); |
||||
} |
||||
|
||||
// AES supports key sizes of only 16, 24, or 32 bytes
|
||||
if (len != 16 && len != 24 && len != 32) { |
||||
return Status::InvalidArgument("Invalid key size in provider."); |
||||
} |
||||
|
||||
// len is in bytes
|
||||
switch (len) { |
||||
case 16: |
||||
key_size_ = KeySize::AES_128; |
||||
break; |
||||
case 24: |
||||
key_size_ = KeySize::AES_192; |
||||
break; |
||||
case 32: |
||||
key_size_ = KeySize::AES_256; |
||||
break; |
||||
} |
||||
|
||||
// get size for context
|
||||
IppStatus ipp_status = ippsAESGetSize(&ctx_size_); |
||||
if (ipp_status != ippStsNoErr) { |
||||
return Status::Aborted("Failed to create provider."); |
||||
} |
||||
|
||||
// allocate memory for context
|
||||
aes_ctx_ = (IppsAESSpec*)(new Ipp8u[ctx_size_]); |
||||
assert(aes_ctx_ != nullptr); |
||||
|
||||
// initialize context
|
||||
const Ipp8u* key = (const Ipp8u*)(cipher); |
||||
ipp_status = |
||||
ippsAESInit(key, static_cast<int>(key_size_), aes_ctx_, ctx_size_); |
||||
|
||||
if (ipp_status != ippStsNoErr) { |
||||
// clean up context and abort!
|
||||
ippsAESInit(0, static_cast<int>(key_size_), aes_ctx_, ctx_size_); |
||||
delete[](Ipp8u*) aes_ctx_; |
||||
return Status::Aborted("Failed to create provider."); |
||||
} |
||||
return Status::OK(); |
||||
} |
||||
|
||||
Status IppcpProvider::CreateNewPrefix(const std::string& /*fname*/, |
||||
char* prefix, size_t prefixLength) const { |
||||
IppStatus ipp_status; |
||||
Ipp32u rnd; |
||||
const size_t rnd_size = sizeof(Ipp32u); |
||||
assert(prefixLength % rnd_size == 0); |
||||
for (size_t i = 0; i < prefixLength; i += rnd_size) { |
||||
// generate a cryptographically secured random number
|
||||
ipp_status = ippsPRNGenRDRAND(&rnd, rnd_size << 3, nullptr); |
||||
if (ipp_status != ippStsNoErr) |
||||
return Status::Aborted(ippcpGetStatusString(ipp_status)); |
||||
memcpy(prefix + i, &rnd, rnd_size); |
||||
} |
||||
IppcpCipherStream cs(aes_ctx_, prefix); |
||||
return cs.Encrypt(0, prefix + IppcpCipherStream::kBlockSize, |
||||
prefixLength - IppcpCipherStream::kBlockSize); |
||||
} |
||||
|
||||
Status IppcpProvider::CreateCipherStream( |
||||
const std::string& /*fname*/, const EnvOptions& /*options*/, Slice& prefix, |
||||
std::unique_ptr<BlockAccessCipherStream>* result) { |
||||
assert(result != nullptr); |
||||
assert(prefix.size() >= IppcpCipherStream::kBlockSize); |
||||
result->reset(new IppcpCipherStream(aes_ctx_, prefix.data())); |
||||
Status ipp_status = (*result)->Decrypt( |
||||
0, (char*)prefix.data() + IppcpCipherStream::kBlockSize, |
||||
prefix.size() - IppcpCipherStream::kBlockSize); |
||||
return ipp_status; |
||||
} |
||||
|
||||
IppcpProvider::~IppcpProvider() { |
||||
ippsAESInit(0, static_cast<int>(key_size_), aes_ctx_, ctx_size_); |
||||
delete[](Ipp8u*) aes_ctx_; |
||||
} |
||||
|
||||
#endif // ROCKSDB_LITE
|
||||
|
||||
} // namespace ROCKSDB_NAMESPACE
|
@ -0,0 +1,73 @@ |
||||
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
||||
// Copyright (c) 2020 Intel Corporation
|
||||
// This source code is licensed under both the GPLv2 (found in the
|
||||
// COPYING file in the root directory) and Apache 2.0 License
|
||||
// (found in the LICENSE.Apache file in the root directory).
|
||||
|
||||
#pragma once |
||||
|
||||
#if !defined(ROCKSDB_LITE) |
||||
|
||||
// Includes Intel's Integrated Performance Primitives for Cryptography (IPPCP).
|
||||
// IPPCP is lightweight cryptography library that is highly-optimized for
|
||||
// various Intel CPUs.
|
||||
//
|
||||
// We use it here to provide an AES-128/192/256 encryption with a CTR mode of
|
||||
// operation.
|
||||
//
|
||||
// Download URL: https://github.com/intel/ipp-crypto.
|
||||
//
|
||||
|
||||
#include <ippcp.h> |
||||
#include <rocksdb/env_encryption.h> |
||||
|
||||
#include <string> |
||||
|
||||
namespace ROCKSDB_NAMESPACE { |
||||
|
||||
// AES-128, AES-192, and AES-256 encryptions are all supported.
|
||||
enum struct KeySize { AES_128 = 16, AES_192 = 24, AES_256 = 32 }; |
||||
|
||||
// This encryption provider uses AES block cipher and a CTR mode of operation
|
||||
// with a cryptographically secure IV that is randomly generated.
|
||||
//
|
||||
// Note: a prefix size of 4096 (4K) is chosen for optimal performance.
|
||||
//
|
||||
class IppcpProvider : public EncryptionProvider { |
||||
public: |
||||
static constexpr size_t kPrefixSize = 4096; |
||||
|
||||
static std::unique_ptr<EncryptionProvider> CreateProvider(); |
||||
|
||||
static const char* kName() { return "ippcp"; } |
||||
|
||||
virtual const char* Name() const override { return kName(); } |
||||
|
||||
virtual size_t GetPrefixLength() const override { return kPrefixSize; } |
||||
|
||||
virtual Status AddCipher(const std::string& /*descriptor*/, |
||||
const char* /*cipher*/, size_t /*len*/, |
||||
bool /*for_write*/) override; |
||||
|
||||
virtual Status CreateNewPrefix(const std::string& fname, char* prefix, |
||||
size_t prefixLength) const override; |
||||
|
||||
virtual Status CreateCipherStream( |
||||
const std::string& fname, const EnvOptions& options, Slice& prefix, |
||||
std::unique_ptr<BlockAccessCipherStream>* result) override; |
||||
|
||||
virtual ~IppcpProvider(); |
||||
|
||||
private: |
||||
int ctx_size_; |
||||
KeySize key_size_; |
||||
IppsAESSpec* aes_ctx_; |
||||
IppcpProvider() |
||||
: ctx_size_(0), key_size_(KeySize::AES_256), aes_ctx_(nullptr) {} |
||||
IppcpProvider(const IppcpProvider&) = delete; |
||||
IppcpProvider& operator=(const IppcpProvider&) = delete; |
||||
}; |
||||
|
||||
} // namespace ROCKSDB_NAMESPACE
|
||||
|
||||
#endif // !defined(ROCKSDB_LITE)
|
@ -0,0 +1,5 @@ |
||||
# Security Policy |
||||
Intel is committed to rapidly addressing security vulnerabilities affecting our customers and providing clear guidance on the solution, impact, severity and mitigation. |
||||
|
||||
## Reporting a Vulnerability |
||||
Please report any security vulnerabilities in this project utilizing the guidelines [here](https://www.intel.com/content/www/us/en/security-center/vulnerability-handling-guidelines.html). |
@ -0,0 +1,61 @@ |
||||
# Copyright (C) 2022 Intel Corporation |
||||
|
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
cmake_minimum_required(VERSION 3.15) |
||||
|
||||
project(ippcp_encryptor_test VERSION 0.0.1) |
||||
|
||||
option(COVERAGE "Enable test coverage report" ON) |
||||
|
||||
set(CMAKE_CXX_STANDARD 17) |
||||
set(CMAKE_CXX_STANDARD_REQUIRED True) |
||||
|
||||
set(ippcp_encryptor_test_CMAKE_EXE_LINKER_FLAGS "-u ippcp_reg") |
||||
add_executable(ippcp_encryptor_test ../ippcp_provider.cc ippcp_encryptor_test.cc) |
||||
|
||||
|
||||
if(NOT DEFINED IPPCRYPTOROOT) |
||||
find_package(ippcp REQUIRED) |
||||
if(ippcp_FOUND) |
||||
message(STATUS "Found ippcp: ${ippcp_DIR}") |
||||
target_link_libraries(ippcp_encryptor_test ippcp::ippcp) |
||||
endif() |
||||
else() |
||||
message(STATUS "Using IPPCRYPTOROOT: ${IPPCRYPTOROOT}") |
||||
include_directories(${IPPCRYPTOROOT}/include) |
||||
target_link_libraries(ippcp_encryptor_test ippcp) |
||||
endif() |
||||
|
||||
if(NOT DEFINED ROCKSDB_PATH) |
||||
find_package(RocksDB REQUIRED) |
||||
if(RocksDB_FOUND) |
||||
message(STATUS "Found RocksDB: ${RocksDB_DIR}") |
||||
target_link_libraries(ippcp_encryptor_test rocksdb) |
||||
endif() |
||||
elseif(DEFINED ROCKSDB_PATH) |
||||
message(STATUS "Using ROCKSDB_PATH: ${ROCKSDB_PATH}") |
||||
include_directories(${ROCKSDB_PATH} ${ROCKSDB_PATH}/include) |
||||
target_link_directories(ippcp_encryptor_test PUBLIC ${ROCKSDB_PATH}) |
||||
target_link_libraries(ippcp_encryptor_test rocksdb) |
||||
endif() |
||||
|
||||
find_package(GTest REQUIRED) |
||||
target_link_libraries(ippcp_encryptor_test gtest) |
||||
|
||||
add_compile_definitions(ROCKSDB_PLATFORM_POSIX) |
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-rtti") |
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti") |
||||
if(COVERAGE) |
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage") |
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") |
||||
endif() |
||||
|
||||
add_custom_target(run |
||||
COMMAND ./ippcp_encryptor_test |
||||
DEPENDS ippcp_encryptor_test |
||||
) |
||||
|
||||
add_custom_target(coverage |
||||
COMMAND lcov --directory . --capture --output-file ippcp_encryptor_test.info && genhtml -o html ippcp_encryptor_test.info |
||||
) |
@ -0,0 +1,430 @@ |
||||
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
||||
// Copyright (c) 2020 Intel Corporation
|
||||
// This source code is licensed under both the GPLv2 (found in the
|
||||
// COPYING file in the root directory) and Apache 2.0 License
|
||||
// (found in the LICENSE.Apache file in the root directory).
|
||||
|
||||
#include <rocksdb/db.h> |
||||
#include <rocksdb/env_encryption.h> |
||||
#include <rocksdb/options.h> |
||||
#include <rocksdb/slice.h> |
||||
#include <rocksdb/utilities/options_util.h> |
||||
#include <rocksdb/utilities/object_registry.h> |
||||
|
||||
#include <cmath> |
||||
#include <iostream> |
||||
#include <string> |
||||
#include <tuple> |
||||
|
||||
#include "../ippcp_provider.h" |
||||
#include <gtest/gtest.h> |
||||
|
||||
namespace ROCKSDB_NAMESPACE |
||||
{ |
||||
|
||||
TEST(IppcpBasicTests, LoadIppcpProvider) |
||||
{ |
||||
std::string IPPCP = IppcpProvider::kName(); |
||||
std::shared_ptr<EncryptionProvider> provider; |
||||
Status s = EncryptionProvider::CreateFromString(ConfigOptions(), IPPCP, &provider); |
||||
ASSERT_TRUE(s.ok()); |
||||
ASSERT_NE(provider, nullptr); |
||||
ASSERT_EQ(provider->Name(), IPPCP); |
||||
std::string cipher_key; |
||||
cipher_key.assign("a6d2ae2816157e2b3c4fcf098815f7x1"); |
||||
s = provider->AddCipher("", cipher_key.c_str(), cipher_key.length(), false); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
; |
||||
} |
||||
|
||||
TEST(IppcpBasicTests, TestAddKeys) |
||||
{ |
||||
std::string IPPCP = IppcpProvider::kName(); |
||||
std::shared_ptr<EncryptionProvider> provider; |
||||
Status s = EncryptionProvider::CreateFromString(ConfigOptions(), IPPCP, &provider); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
; |
||||
ASSERT_NE(provider, nullptr); |
||||
std::string cipher_key; |
||||
cipher_key.assign("a6d2ae2816157e2b3c4fcf098815f7x2"); |
||||
s = provider->AddCipher("", cipher_key.c_str(), cipher_key.length(), false); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
|
||||
provider.reset(); |
||||
s = EncryptionProvider::CreateFromString(ConfigOptions(), IPPCP, &provider); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
; |
||||
ASSERT_NE(provider, nullptr); |
||||
cipher_key.assign("a6d2ae2816157e2beeeeeeee"); |
||||
s = provider->AddCipher("", cipher_key.c_str(), cipher_key.length(), false); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
|
||||
provider.reset(); |
||||
cipher_key.assign("a6d2ae2816157e21"); |
||||
s = EncryptionProvider::CreateFromString(ConfigOptions(), IPPCP, &provider); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
ASSERT_NE(provider, nullptr); |
||||
s = provider->AddCipher("", cipher_key.c_str(), cipher_key.length(), false); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
} |
||||
|
||||
TEST(IppcpBasicTests, TestIncorrectKeyLength) |
||||
{ |
||||
std::string IPPCP = IppcpProvider::kName(); |
||||
std::shared_ptr<EncryptionProvider> provider; |
||||
Status s = EncryptionProvider::CreateFromString(ConfigOptions(), IPPCP, &provider); |
||||
ASSERT_TRUE(s.ok()); |
||||
ASSERT_NE(provider, nullptr); |
||||
std::string cipher_key; |
||||
|
||||
// empty encryption key
|
||||
cipher_key.assign(""); |
||||
s = provider->AddCipher("", cipher_key.c_str(), cipher_key.length(), false); |
||||
ASSERT_TRUE(s.IsInvalidArgument()) << s.ToString(); |
||||
|
||||
// incoorect encryption key length
|
||||
cipher_key.assign("a6d2ae2"); |
||||
s = provider->AddCipher("", cipher_key.c_str(), cipher_key.length(), false); |
||||
ASSERT_TRUE(s.IsInvalidArgument()) << s.ToString(); |
||||
} |
||||
|
||||
TEST(IppcpBasicTests, TestAddingMultipleKeys) |
||||
{ |
||||
std::string IPPCP = IppcpProvider::kName(); |
||||
std::shared_ptr<EncryptionProvider> provider; |
||||
Status s = EncryptionProvider::CreateFromString(ConfigOptions(), IPPCP, &provider); |
||||
ASSERT_TRUE(s.ok()); |
||||
ASSERT_NE(provider, nullptr); |
||||
std::string cipher_key; |
||||
// correct encryption key
|
||||
cipher_key.assign("a6d2ae2816157e21"); |
||||
s = provider->AddCipher("", cipher_key.c_str(), cipher_key.length(), false); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
|
||||
// adding multiple cipher/encryption keys not allowed
|
||||
cipher_key.assign("a6d2ae281wwwwddd22222213"); |
||||
s = provider->AddCipher("", cipher_key.c_str(), cipher_key.length(), false); |
||||
ASSERT_TRUE(s.IsInvalidArgument()) << s.ToString(); |
||||
} |
||||
|
||||
TEST(IppcpEncryptionTests, CounterBlkTests) |
||||
{ |
||||
std::string IPPCP = IppcpProvider::kName(); |
||||
std::shared_ptr<EncryptionProvider> provider; |
||||
// creating ipp provider and setting cipher key
|
||||
Status s = EncryptionProvider::CreateFromString(ConfigOptions(), IPPCP, &provider); |
||||
ASSERT_TRUE(s.ok()); |
||||
ASSERT_NE(provider, nullptr); |
||||
std::string cipher_key; |
||||
cipher_key.assign("a6d2ae2816157e2b3c4fcf098815f7x2"); |
||||
s = provider->AddCipher("", cipher_key.c_str(), cipher_key.length(), false); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
// initilizing prefix which sets the 128 initVector data memmber
|
||||
// the first 8 bytes will be used for counter
|
||||
size_t prefixLen = 16; // minimum size of prefix is 16(blockSize)
|
||||
uint8_t ctr[] = {0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; |
||||
Slice prefix((char *)ctr, prefixLen); |
||||
|
||||
std::unique_ptr<BlockAccessCipherStream> stream; |
||||
const EnvOptions options; |
||||
// creating cipher stream object to perform encryption and decryption
|
||||
s = provider->CreateCipherStream("", options, prefix, &stream); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
|
||||
std::string input1, input2, input3, plainTxt; |
||||
uint64_t offset = 0; // offset where from we need to perform encryption/decryption
|
||||
plainTxt = ""; |
||||
input1.assign("1 input for CounterBlk hellooo0 "); |
||||
input2.assign("2 input for CounterBlk hellooo0 "); |
||||
input3.assign("3 input for CounterBlk helloo0 "); |
||||
// concatenate the strings and encrypt them
|
||||
plainTxt = input1 + input2 + input3; |
||||
s = stream->Encrypt(offset, (char *)plainTxt.c_str(), plainTxt.length()); // does in place encryption so plainTxt will be encrypted now
|
||||
s = stream->Decrypt(offset, (char *)plainTxt.c_str(), plainTxt.length()); // in .place decryption
|
||||
ASSERT_EQ(input1 + input2 + input3, plainTxt) << " both are strings are same after decryption!!"; |
||||
} |
||||
|
||||
/*
|
||||
This test checks wraparound condition for counter.The plugin code uses 64 bit intrinsic _mm_add_epi64 for addition as index is 64bits. |
||||
plugin counter for all ff -> (ff ff ff ff ff ff ff ff 0 0 0 0 0 0 0 0) and (ff ff ff ff ff ff ff ff 0 0 0 0 0 0 0 1) so on |
||||
if the kCounterLen passed to ipp lib is 128 then it use all 128 bits for addition which means counter created |
||||
by plugin and ipp code will differ as it will rollover to all 0. |
||||
if all FF counter is passed to ipp then new counter created ->() 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ),( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2) etc |
||||
|
||||
To fix this issue the counter addition bit length needs to be same in both plugin and ipp lib code |
||||
so kCounterLen needs to be 64 bits. |
||||
|
||||
This test will fail if kCounterLen is 128 |
||||
*/ |
||||
TEST(IppcpEncryptionTests, CounterBlkOverFlowTests) |
||||
{ |
||||
std::string IPPCP = IppcpProvider::kName(); |
||||
std::shared_ptr<EncryptionProvider> provider; |
||||
// creating ipp provider and setting cipher key
|
||||
Status s = EncryptionProvider::CreateFromString(ConfigOptions(), IPPCP, &provider); |
||||
ASSERT_TRUE(s.ok()); |
||||
ASSERT_NE(provider, nullptr); |
||||
std::string cipher_key; |
||||
cipher_key.assign("a6d2ae2816157e2b3c4fcf098815f7x2"); |
||||
s = provider->AddCipher("", cipher_key.c_str(), cipher_key.length(), false); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
|
||||
// creating prefix which sets the 128 initVector data memmber
|
||||
size_t prefixLen = 16; // minimum size of prefix is 16
|
||||
// setting prefix/counter to all ff's to check the overflow
|
||||
uint8_t ctr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; |
||||
Slice prefix((char *)ctr, prefixLen); |
||||
// creating cipher stream object to perform encryption and decryption
|
||||
std::unique_ptr<BlockAccessCipherStream> stream; |
||||
const EnvOptions options; |
||||
s = provider->CreateCipherStream("", options, prefix, &stream); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
|
||||
// creating string each of 16 byte(blocksize) for encryption
|
||||
std::string str1, str2, str3; |
||||
str1.assign("1111111111111111"); |
||||
str2.assign("2222222222222222"); |
||||
str3.assign("3333333333333333"); |
||||
|
||||
std::string encryptedString = ""; |
||||
encryptedString += str1; |
||||
encryptedString += str2; |
||||
encryptedString += str3; |
||||
// encrypted all the strings in one go.Here ipp lib will create counter block for 2nd and 3rd string block
|
||||
s = stream->Encrypt(0, (char *)encryptedString.c_str(), encryptedString.length()); |
||||
std::string cipherTxt = encryptedString.substr(str1.length()); |
||||
// decrypt the encrypted string from str2 onwards i.e from block 2 onwards
|
||||
s = stream->Decrypt(str1.length(), (char *)cipherTxt.c_str(), cipherTxt.length()); |
||||
// the decrypted string should match the str2 + str3
|
||||
ASSERT_EQ((str2 + str3), cipherTxt) << " both are strings are same after decryption!!"; |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
} |
||||
|
||||
/*
|
||||
This test encrypts the input data and then decrypts it. Decrypted data should match the input for success. |
||||
This Matches RocksDB Encryption API flow. |
||||
*/ |
||||
TEST(IppcpEncryptionTests, EncryptDecryptTest) |
||||
{ |
||||
std::string IPPCP = IppcpProvider::kName(); |
||||
std::shared_ptr<EncryptionProvider> provider; |
||||
Status s = EncryptionProvider::CreateFromString(ConfigOptions(), IPPCP, &provider); |
||||
ASSERT_TRUE(s.ok()); |
||||
ASSERT_NE(provider, nullptr); |
||||
|
||||
std::string cipher_key; |
||||
cipher_key.assign("a6d2ae2816157e2b3c4fcf098815f7x2"); |
||||
s = provider->AddCipher("", cipher_key.c_str(), cipher_key.length(), false); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
|
||||
size_t prefixLen = provider->GetPrefixLength(); |
||||
ASSERT_GT(prefixLen, 0); |
||||
char *buf = (char *)malloc(prefixLen); |
||||
ASSERT_NE(buf, nullptr); |
||||
std::unique_ptr<BlockAccessCipherStream> stream; |
||||
const EnvOptions options; |
||||
s = provider->CreateNewPrefix("", buf, prefixLen); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
Slice prefix(buf, prefixLen); |
||||
|
||||
s = provider->CreateCipherStream("", options, prefix, &stream); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
|
||||
std::string input, plainTxt; |
||||
uint64_t offset = prefixLen; |
||||
input.assign("test ippcp crypto"); |
||||
plainTxt = input; // input becomes cipher txt in below API.
|
||||
s = stream->Encrypt(offset, (char *)input.c_str(), input.length()); // does in place encryption
|
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
s = stream->Decrypt(offset, (char *)input.c_str(), input.length()); |
||||
ASSERT_EQ(plainTxt, input) << " both are strings are same after decryption!!"; |
||||
free(buf); |
||||
} |
||||
|
||||
/*
|
||||
This test encrypts the multple input data and then decrypts it in one go. |
||||
Decrypted data should match the combined input for success. |
||||
This is to test the random decryption functionality. |
||||
*/ |
||||
|
||||
TEST(IppcpEncryptionTests, RandomDecryptionTests) |
||||
{ |
||||
std::string IPPCP = IppcpProvider::kName(); |
||||
std::shared_ptr<EncryptionProvider> provider; |
||||
Status s = EncryptionProvider::CreateFromString(ConfigOptions(), IPPCP, &provider); |
||||
ASSERT_TRUE(s.ok()); |
||||
ASSERT_NE(provider, nullptr); |
||||
|
||||
std::string cipher_key; |
||||
cipher_key.assign("a6d2ae2816157e2b3c4fcf098815f7x2"); |
||||
s = provider->AddCipher("", cipher_key.c_str(), cipher_key.length(), false); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
|
||||
size_t prefixLen = provider->GetPrefixLength(); |
||||
ASSERT_GT(prefixLen, 0); |
||||
char *buf = (char *)malloc(prefixLen); |
||||
ASSERT_NE(buf, nullptr); |
||||
s = provider->CreateNewPrefix("", buf, prefixLen); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
Slice prefix(buf, prefixLen); |
||||
|
||||
std::unique_ptr<BlockAccessCipherStream> stream; |
||||
const EnvOptions options; |
||||
s = provider->CreateCipherStream("", options, prefix, &stream); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
|
||||
std::string input1, plainTxt, cipherTxt; |
||||
uint64_t offset = prefixLen; |
||||
|
||||
input1.assign("1 input for encryption hellooo0 "); |
||||
plainTxt = input1; |
||||
s = stream->Encrypt(offset, (char *)input1.c_str(), input1.length()); // does in place encryption
|
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
cipherTxt = input1; |
||||
offset += input1.length(); |
||||
|
||||
std::string input2; |
||||
input2.assign("2 input for encryption hellooo0 "); |
||||
plainTxt += input2; |
||||
s = stream->Encrypt(offset, (char *)input2.c_str(), input2.length()); // does in place encryption
|
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
cipherTxt += input2; |
||||
offset += input2.length(); |
||||
|
||||
std::string input3; |
||||
input3.assign("3 input for encryption helloo0 "); |
||||
plainTxt += input3; |
||||
s = stream->Encrypt(offset, (char *)input3.c_str(), input3.length()); // does in place encryption
|
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
cipherTxt += input3; |
||||
// decrypt the all the input string in one go.
|
||||
s = stream->Decrypt(prefixLen, (char *)cipherTxt.c_str(), cipherTxt.length()); |
||||
|
||||
ASSERT_EQ(plainTxt, cipherTxt) << " both are strings are same after decryption!!"; |
||||
free(buf); |
||||
} |
||||
|
||||
TEST(IppcpEncryptionTests, EncryptDecryptWithDifferentKeys) |
||||
{ |
||||
std::string IPPCP = IppcpProvider::kName(); |
||||
std::shared_ptr<EncryptionProvider> provider; |
||||
Status s = EncryptionProvider::CreateFromString(ConfigOptions(), IPPCP, &provider); |
||||
ASSERT_TRUE(s.ok()); |
||||
ASSERT_NE(provider, nullptr); |
||||
|
||||
std::string cipher_key; |
||||
cipher_key.assign("a6d2ae2816157e2b3c4fcf098815f7x2"); |
||||
s = provider->AddCipher("", cipher_key.c_str(), cipher_key.length(), false); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
|
||||
size_t prefixLen = provider->GetPrefixLength(); |
||||
ASSERT_GT(prefixLen, 0); |
||||
char *buf = (char *)malloc(prefixLen); |
||||
ASSERT_NE(buf, nullptr); |
||||
std::unique_ptr<BlockAccessCipherStream> stream; |
||||
const EnvOptions options; |
||||
s = provider->CreateNewPrefix("", buf, prefixLen); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
Slice prefix(buf, prefixLen); |
||||
s = provider->CreateCipherStream("", options, prefix, &stream); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
|
||||
std::string input, plainTxt, cipherTxt; |
||||
uint64_t offset = prefixLen; |
||||
|
||||
input.assign("test ippcp crypto"); |
||||
plainTxt = input; |
||||
|
||||
s = stream->Encrypt(offset, (char *)input.c_str(), input.length()); // does in place encryption
|
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
cipherTxt = input; // encrypted txt
|
||||
|
||||
provider.reset(); |
||||
s = EncryptionProvider::CreateFromString(ConfigOptions(), IPPCP, &provider); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
; |
||||
ASSERT_NE(provider, nullptr); |
||||
|
||||
// change the key
|
||||
cipher_key.assign("a6d2ae2816157e2b"); |
||||
s = provider->AddCipher("", cipher_key.c_str(), cipher_key.length(), false); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
s = stream->Decrypt(offset, (char *)cipherTxt.c_str(), input.length()); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
ASSERT_NE(plainTxt, cipherTxt) << " both are strings are same after decryption!!"; |
||||
free(buf); |
||||
} |
||||
|
||||
struct TestParam |
||||
{ |
||||
TestParam(std::string _cipher_desc, std::string _cipher_key, std::string _plainTxt = "") : cipher_desc(_cipher_desc), cipher_key(_cipher_key), plainTxt(_plainTxt) {} |
||||
|
||||
std::string cipher_desc; |
||||
std::string cipher_key; |
||||
std::string plainTxt; |
||||
std::string GetOpts() |
||||
{ |
||||
return "cipher_desc = " + cipher_desc + "; cipher_key = " + cipher_key + "; cipher_size = " + std::to_string(cipher_key.length()) + "; plaintxt = " + plainTxt; |
||||
} |
||||
}; |
||||
|
||||
class IppcpProviderTest : public testing::TestWithParam<std::tuple<std::string, std::string, std::string>> |
||||
{ |
||||
public: |
||||
static void SetUpTestSuite() |
||||
{ |
||||
ObjectLibrary::Default()->AddFactory<EncryptionProvider>( |
||||
IppcpProvider::kName(), |
||||
[](const std::string & /* uri */, std::unique_ptr<EncryptionProvider> *f, |
||||
std::string * /* errmsg */) |
||||
{ |
||||
*f = IppcpProvider::CreateProvider(); |
||||
return f->get(); |
||||
}); |
||||
} |
||||
void SetUp() override |
||||
{ |
||||
TestParam test_param(std::get<0>(GetParam()), std::get<1>(GetParam()), std::get<2>(GetParam())); |
||||
ConfigOptions config_options; |
||||
Status s = EncryptionProvider::CreateFromString(config_options, IppcpProvider::kName(), &provider); |
||||
} |
||||
std::shared_ptr<EncryptionProvider> provider; |
||||
const EnvOptions soptions_; |
||||
}; |
||||
|
||||
TEST_P(IppcpProviderTest, EncryptDecrypt) |
||||
{ |
||||
TestParam test_param(std::get<0>(GetParam()), std::get<1>(GetParam()), std::get<2>(GetParam())); |
||||
Status s = provider->AddCipher(test_param.cipher_desc, (char *)test_param.cipher_key.c_str(), test_param.cipher_key.length(), false); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
|
||||
size_t prefixLen = 16; // minimum size of prefix is 16(blockSize)
|
||||
uint8_t ctr[] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; |
||||
Slice prefix((char *)ctr, prefixLen); |
||||
|
||||
std::unique_ptr<BlockAccessCipherStream> stream; |
||||
s = provider->CreateCipherStream("", soptions_, prefix, &stream); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
|
||||
std::string input = test_param.plainTxt; |
||||
s = stream->Encrypt(0, (char *)input.c_str(), input.length()); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
s = stream->Decrypt(0, (char *)input.c_str(), input.length()); |
||||
ASSERT_TRUE(s.ok()) << s.ToString(); |
||||
ASSERT_TRUE(test_param.plainTxt == input) << " both are strings are same after decryption!!"; |
||||
} |
||||
|
||||
// working but uses cartesian product
|
||||
INSTANTIATE_TEST_SUITE_P(IppcpProviderTestInstance, |
||||
IppcpProviderTest, |
||||
testing::Combine(testing::Values("ippcp_test_aes"), // key description
|
||||
testing::Values("a6d2ae2816157e2b3c4fcf098815f7xb", "a6d2ae2816157e2334512345", "a6d2ae2816157e23"), // encryption key // offset for encryption and decryption
|
||||
testing::Values("Hello world", "Helloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo worldddddddddddddddddddddddddddddddd 111111111111111111111111111111111111111111111111111111111111111"))); // plain text to encrypt
|
||||
|
||||
} // end of namespace
|
||||
|
||||
int main(int argc, char *argv[]) |
||||
{ |
||||
::testing::InitGoogleTest(&argc, argv); |
||||
return RUN_ALL_TESTS(); |
||||
} |
Loading…
Reference in new issue