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