avs-device-sdk/core/Crypto/acsdkPkcs11/test/PKCS11KeyTest.cpp

178 lines
6.2 KiB
C++

/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
#include <string>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <acsdkPkcs11/private/PKCS11Functions.h>
#include <acsdkPkcs11/private/PKCS11Slot.h>
#include <acsdkPkcs11/private/PKCS11Session.h>
#include <acsdkPkcs11/private/PKCS11Key.h>
#include <acsdkCryptoInterfaces/KeyStoreInterface.h>
namespace alexaClientSDK {
namespace acsdkPkcs11 {
namespace test {
using namespace ::testing;
using namespace ::alexaClientSDK::acsdkCryptoInterfaces;
/// @private
static const KeyStoreInterface::IV
IV{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
/// @private
static const KeyStoreInterface::IV IV_GCM{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c};
/// @private
static const KeyStoreInterface::DataBlock PLAINTEXT{
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'i', 'o', 'p', 'q', 'r', 's', 't', 'u',
};
TEST(PKCS11KeyTest, test_encryptDecryptAes256Cbc) {
auto functions = PKCS11Functions::create(PKCS11_LIBRARY);
ASSERT_NE(nullptr, functions);
std::shared_ptr<PKCS11Slot> slot;
ASSERT_TRUE(functions->findSlotByTokenName(PKCS11_TOKEN_NAME, slot));
ASSERT_NE(nullptr, slot);
auto session = slot->openSession();
ASSERT_NE(nullptr, session);
ASSERT_TRUE(session->logIn(PKCS11_PIN));
auto key = session->findKey({PKCS11_KEY_NAME, AlgorithmType::AES_256_CBC});
ASSERT_NE(nullptr, key);
KeyStoreInterface::Tag tag;
KeyStoreInterface::DataBlock aad;
// Encrypt
KeyStoreInterface::DataBlock ciphertext;
ASSERT_TRUE(key->encrypt(AlgorithmType::AES_256_CBC, IV, aad, PLAINTEXT, ciphertext, tag));
EXPECT_NE(PLAINTEXT, ciphertext);
// Decrypt
KeyStoreInterface::DataBlock plaintext;
ASSERT_TRUE(key->decrypt(AlgorithmType::AES_256_CBC, IV, aad, ciphertext, tag, plaintext));
EXPECT_EQ(PLAINTEXT, plaintext);
key.reset();
ASSERT_TRUE(session->logOut());
}
TEST(PKCS11KeyTest, test_encryptDecryptErrors) {
auto functions = PKCS11Functions::create(PKCS11_LIBRARY);
ASSERT_NE(nullptr, functions);
std::shared_ptr<PKCS11Slot> slot;
ASSERT_TRUE(functions->findSlotByTokenName(PKCS11_TOKEN_NAME, slot));
ASSERT_NE(nullptr, slot);
auto session = slot->openSession();
ASSERT_NE(nullptr, session);
ASSERT_TRUE(session->logIn(PKCS11_PIN));
auto key = session->findKey({PKCS11_KEY_NAME, AlgorithmType::AES_256_CBC});
ASSERT_NE(nullptr, key);
KeyStoreInterface::Tag tag;
KeyStoreInterface::DataBlock aad;
// Encrypt with bad IV
std::vector<uint8_t> output;
ASSERT_FALSE(key->encrypt(AlgorithmType::AES_256_CBC, aad, {}, PLAINTEXT, output, tag));
// Decrypt with bad IV
ASSERT_FALSE(key->decrypt(AlgorithmType::AES_256_CBC, aad, {}, PLAINTEXT, output, tag));
}
TEST(PKCS11KeyTest, test_encryptDecryptAes256CbcPad) {
auto functions = PKCS11Functions::create(PKCS11_LIBRARY);
ASSERT_NE(nullptr, functions);
std::shared_ptr<PKCS11Slot> slot;
ASSERT_TRUE(functions->findSlotByTokenName(PKCS11_TOKEN_NAME, slot));
ASSERT_NE(nullptr, slot);
auto session = slot->openSession();
ASSERT_NE(nullptr, session);
ASSERT_TRUE(session->logIn(PKCS11_PIN));
auto key = session->findKey({PKCS11_KEY_NAME, AlgorithmType::AES_256_CBC_PAD});
ASSERT_NE(nullptr, key);
KeyStoreInterface::Tag tag;
KeyStoreInterface::DataBlock aad;
// Encrypt
KeyStoreInterface::DataBlock ciphertext;
ASSERT_TRUE(key->encrypt(AlgorithmType::AES_256_CBC_PAD, IV, aad, PLAINTEXT, ciphertext, tag));
EXPECT_NE(PLAINTEXT, ciphertext);
// Decrypt
KeyStoreInterface::DataBlock plaintext;
ASSERT_TRUE(key->decrypt(AlgorithmType::AES_256_CBC_PAD, IV, aad, ciphertext, tag, plaintext));
EXPECT_EQ(PLAINTEXT, plaintext);
ASSERT_TRUE(session->logOut());
}
TEST(PKCS11KeyTest, test_encryptDecryptAes256Gcm) {
auto functions = PKCS11Functions::create(PKCS11_LIBRARY);
ASSERT_NE(nullptr, functions);
std::shared_ptr<PKCS11Slot> slot;
ASSERT_TRUE(functions->findSlotByTokenName(PKCS11_TOKEN_NAME, slot));
ASSERT_NE(nullptr, slot);
auto session = slot->openSession();
ASSERT_NE(nullptr, session);
ASSERT_TRUE(session->logIn(PKCS11_PIN));
auto key = session->findKey({PKCS11_KEY_NAME, AlgorithmType::AES_256_GCM});
ASSERT_NE(nullptr, key);
KeyStoreInterface::Tag tag;
KeyStoreInterface::DataBlock aad{0, 1, 2};
// Encrypt
KeyStoreInterface::DataBlock ciphertext;
ASSERT_TRUE(key->encrypt(AlgorithmType::AES_256_GCM, IV_GCM, aad, PLAINTEXT, ciphertext, tag));
EXPECT_NE(PLAINTEXT, ciphertext);
ASSERT_EQ(16u, tag.size());
// Decrypt
KeyStoreInterface::DataBlock plaintext;
ASSERT_TRUE(key->decrypt(AlgorithmType::AES_256_GCM, IV_GCM, aad, ciphertext, tag, plaintext));
EXPECT_EQ(PLAINTEXT, plaintext);
ASSERT_TRUE(session->logOut());
}
TEST(PKCS11KeyTest, test_getKeyAttributes) {
auto functions = PKCS11Functions::create(PKCS11_LIBRARY);
ASSERT_NE(nullptr, functions);
std::shared_ptr<PKCS11Slot> slot;
ASSERT_TRUE(functions->findSlotByTokenName(PKCS11_TOKEN_NAME, slot));
ASSERT_NE(nullptr, slot);
auto session = slot->openSession();
ASSERT_NE(nullptr, session);
ASSERT_TRUE(session->logIn(PKCS11_PIN));
auto key = session->findKey({PKCS11_KEY_NAME, AlgorithmType::AES_256_CBC_PAD});
ASSERT_NE(nullptr, key);
KeyStoreInterface::KeyChecksum checksum;
bool neverExtractable = false;
ASSERT_TRUE(key->getAttributes(checksum, neverExtractable));
ASSERT_EQ(3u, checksum.size());
ASSERT_TRUE(neverExtractable);
}
} // namespace test
} // namespace acsdkPkcs11
} // namespace alexaClientSDK