Files
whitebox/crypto_utils/rsa_util.h
Aaron Vaage 77f7ef98c0 Initial Code Drop
This is the initial code drop of the reference implementation and
test cases for the Widevine Whitebox API.

In this drop, the full reference implementation for the AEAD
white-box is provided and all test cases verifying the top-level
behave have are enabled. Since the implementations can vary so much
the testing is mostly left to verifying the return codes for specific
parameter conditions.

A full reference implementation for the license white-box is provided,
however not all tests are implemented or enabled. A number of tests
have been disabled as they required a loaded license and test licenses
are still being worked on.

The two license white-box API functions that are the further from
competition are ProcessLicenseResponse() and MaskedDecryt().
ProcessLicenseResponse() is still being worked on and MaskedDecrypt()
is waiting on Decrypt() to be fully functional.

Most tests focus on verifying return code for specific parameter
conditions, but as test licenses are created, tests looking to test
the internal behaviour of license management will be added to
ProcessLicenseResponse(), Decrypt(), and MaskedDecrypt().
2020-05-18 19:45:53 -07:00

211 lines
10 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// Copyright 2016 Google LLC.
//
// This software is licensed under the terms defined in the Widevine Master
// License Agreement. For a copy of this agreement, please contact
// widevine-licensing@google.com.
////////////////////////////////////////////////////////////////////////////////
//
// Description:
// RSA utility functions for serializing and deserializing RSA keys,
// encryption, and signing.
#ifndef WHITEBOX_CRYPTO_UTILS_RSA_UTIL_H_
#define WHITEBOX_CRYPTO_UTILS_RSA_UTIL_H_
#include <string>
#include "third_party/boringssl/src/include/openssl/rsa.h"
namespace widevine {
namespace rsa_util {
// Serialize RSA private key into DER encoded PKCS#1 RSAPrivateKey.
// - private_key is the RSA key to be serialized, which must not be NULL.
// - serialized_private_key is a pointer to the std::string to hold the
// serialized
// PKCS#1 RSAPrivateKey object. Caller retains ownership of the string. This
// parameter must not be NULL.
// Returns true if successful, false otherwise.
bool SerializeRsaPrivateKey(const RSA* private_key,
std::string* serialized_private_key);
// Deserialize RSA private key from DER encoded PKCS#1 RSAPrivateKey.
// - serialized_private_key is the DER-encoded PKCS#1 RSAPrivateKey to be
// deserialized.
// - private_key is a pointer to an RSA structure pointer to point to a newly
// allocated RSA structure. Caller assumes ownership of the new RSA pointer,
// which is not allocated if the method fails. This parameter must not be
// NULL.
// Returns true if successful, false otherwise.
bool DeserializeRsaPrivateKey(const std::string& serialized_private_key,
RSA** private_key);
// Serialize RSA key into DER encoded PKCS#1 RSAPublicKey.
// - public_key is the RSA key to be serialized, which must not be NULL.
// - serialized_public_key is a pointer to the std::string to hold the
// serialized
// PKCS#1 RSAPublicKey object. Caller retains ownership of the string. This
// parameter must not be NULL.
// Returns true if successful, false otherwise.
bool SerializeRsaPublicKey(const RSA* public_key,
std::string* serialized_public_key);
// Deserialize RSA public key from DER encoded PKCS#1 RSAPublicKey.
// - serialized_public_key is the DER-encoded PKCS#1 RSAPublicKey to be
// deserialized.
// - public_key is a pointer to an RSA structure pointer to point to a newly
// allocated RSA structure. Caller assumes ownership of the new RSA pointer,
// which is not allocated if the method fails. This parameter must not be
// NULL.
// Returns true if successful, false otherwise.
bool DeserializeRsaPublicKey(const std::string& serialized_public_key,
RSA** public_key);
// Serialize RSA private key into DER encoded PKCS#8 PrivateKeyInfo.
// - private_key is the RSA key to be serialized, which must not be NULL.
// - serialized_private_key is a pointer to the std::string to hold the
// serialized
// PKCS#8 PrivateKeyInfo object. Caller retains ownership of the string. This
// parameter must not be NULL.
// Returns true if successful, false otherwise.
bool SerializePrivateKeyInfo(const RSA* private_key,
std::string* serialized_private_key);
// Deserialize RSA private key from DER encoded PKCS#8 PrivateKeyInfo.
// - serialized_private_key is the DER-encoded PKCS#8 PrivateKeyInfo to be
// deserialized.
// - private_key is a pointer to an RSA structure pointer to point to a newly
// allocated RSA structure. Caller assumes ownership of the new RSA pointer,
// which is not allocated if the method fails. This parameter must not be
// NULL.
// Returns true if successful, false otherwise.
bool DeserializePrivateKeyInfo(const std::string& serialized_private_key,
RSA** private_key);
// Convert DER-encoded PKCS#1 RSAPrivateKey to DER-encoded PKCS#8
// PrivateKeyInfo.
// - rsa_private_key is the PKCS#1 RSAPrivateKey to be converted.
// - private_key_info is a pointer to std::string to hold the PKCS#8
// PrivateKeyInfo.
// The caller retains ownership of this parameter, which must not be NULL.
// Returns true if successful, false otherwise.
bool RsaPrivateKeyToPrivateKeyInfo(const std::string& rsa_private_key,
std::string* private_key_info);
// Convert DER-encoded PKCS#8 PrivateKeyInfo to DER-encoded PKCS#1
// RSAPrivateKey.
// - private_key_info is the PKCS#8 PrivateKeyInfo to be converted.
// - rsa_private_key is a pointer to std::string to hold the PKCS#1
// RSAPrivateKey.
// The caller retains ownership of this parameter, which must not be NULL.
// Returns true if successful, false otherwise.
bool PrivateKeyInfoToRsaPrivateKey(const std::string& private_key_info,
std::string* rsa_private_key);
// Serialize RSA private key into DER encoded PKCS#8 EncryptedPrivateKeyInfo.
// - private_key is the RSA key to be serialized, which must not be NULL.
// - passphrase is the password to use for PKCS#5 v2.0 3DES encryption.
// - serialized_private_key is a pointer to the std::string to hold the
// serialized
// PKCS#8 EncryptedPrivateKeyInfo object. Caller retains ownership of the
// string. This parameter must not be NULL.
// Returns true if successful, false otherwise.
bool SerializeEncryptedPrivateKeyInfo(const RSA* private_key,
const std::string& passphrase,
std::string* serialized_private_key);
// Deserialize RSA private key from DER encoded PKCS#8 EncryptedPrivateKeyInfo.
// - serialized_private_key is the DER-encoded PKCS#8 EncryptedPrivateKeyInfo to
// be deserialized.
// - passphrase is the password to use for key decryption.
// - private_key is a pointer to an RSA structure pointer to point to a newly
// allocated RSA structure. Caller assumes ownership of the new RSA pointer,
// which is not allocated if the method fails. This parameter must not be
// NULL.
// Returns true if successful, false otherwise.
bool DeserializeEncryptedPrivateKeyInfo(
const std::string& serialized_private_key,
const std::string& passphrase,
RSA** private_key);
// Convert DER-encoded PKCS#1 RSAPrivateKey to DER-encoded PKCS#8
// EncryptedPrivateKeyInfo.
// - rsa_private_key is the PKCS#1 RSAPrivateKey to be converted.
// - passphrase is the password to use for PKCS#5 v2.1 AES-256-CBC encryption.
// - private_key_info is a pointer to std::string to hold the PKCS#8
// EncryptedPrivateKeyInfo.
// The caller retains ownership of this parameter, which must not be NULL.
// Returns true if successful, false otherwise.
bool RsaPrivateKeyToEncryptedPrivateKeyInfo(const std::string& rsa_private_key,
const std::string& passphrase,
std::string* private_key_info);
// Convert DER-encoded PKCS#8 EncryptedPrivateKeyInfo to DER-encoded PKCS#1
// RSAPrivateKey.
// - private_key_info is the PKCS#8 EncryptedPrivateKeyInfo to be converted.
// - passphrase is the password to use for key decryption.
// - rsa_private_key is a pointer to std::string to hold the PKCS#1
// RSAPrivateKey.
// The caller retains ownership of this parameter, which must not be NULL.
// Returns true if successful, false otherwise.
bool EncryptedPrivateKeyInfoToRsaPrivateKey(const std::string& private_key_info,
const std::string& passphrase,
std::string* rsa_private_key);
// This method changes |rsa| to use the more common, but not FIPS 186-4
// compliant, computation for the RSA private exponent (d). This used to be the
// form produced by the BoringSSL method RSA_generate_key. This changed in this
// CL: https://boringssl-review.googlesource.com/c/boringssl/+/15944
//
// This method is used to produce a "backward-compatible" version. Some vendor
// RSA implementations do not handle the new computation properly.
//
// - rsa is the openssl RSA structure. Must not be null. Caller retains
// ownership.
//
// Returns true if the key was successfully updated, false otherwise.
bool ConvertToEulerTotient(RSA* rsa);
// This is wrapper to the other SwitchToEulerTotient that supports deserializing
// and serializing from and to a DER encoded PKCS#1 RSAPrivateKey.
//
// - private_key is the DER-encoded PKCS#1 RSAPrivateKey to be
// deserialized and converted.
// - euler_private_key is a pointer to the std::string to hold the converted and
// serialized PKCS#1 RSAPrivateKey object. Caller retains ownership of the
// string. This parameter must not be NULL.
// Returns true if the key was successfully updated, false otherwise.
bool ConvertToEulerTotient(const std::string& private_key,
std::string* euler_private_key);
// This method changes |rsa| to use the FIPS 186-4 compliant computation for d.
// This uses the Carmichael totient. This is equivalent to the way the key
// is generated in BoringSSL as of this change:
// https://boringssl-review.googlesource.com/c/boringssl/+/15944
//
// This method is mostly used for testing. It allows tests to convert back and
// forth between forms and verify the output.
//
// Returns true if the key can be successfully updated, false otherwise.
bool ConvertToCarmichaelTotient(RSA* rsa);
// This is wrapper to the other SwitchToCarmichaelTotient that supports
// deserializing and serializing from and to a DER encoded PKCS#1 RSAPrivateKey.
//
// - private_key is the DER-encoded PKCS#1 RSAPrivateKey to be
// deserialized and converted.
// - carmichael_private_key is a pointer to the std::string to hold the
// converted and
// serialized PKCS#1 RSAPrivateKey object. Caller retains ownership of the
// string. This parameter must not be NULL.
// Returns true if the key was successfully updated, false otherwise.
bool ConvertToCarmichaelTotient(const std::string& private_key,
std::string* carmichael_private_key);
} // namespace rsa_util
} // namespace widevine
#endif // WHITEBOX_CRYPTO_UTILS_RSA_UTIL_H_