Files
android/libwvdrmengine/oemcrypto/test/oec_key_deriver.h
Fred Gylys-Colwell e51c9fbbb8 Update license comment
Merge from Widevine repo of http://go/wvgerrit/121950

Remove term "Master" from "Widevine Master License Agreement".

Bug: 168562298
Change-Id: I655babf1bc447f4872f6a0f849107262be42df7a
2021-04-12 14:10:08 -07:00

94 lines
3.5 KiB
C++

// Copyright 2019 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine
// License Agreement.
//
#ifndef CDM_OEC_KEY_DERIVER_H_
#define CDM_OEC_KEY_DERIVER_H_
#include <openssl/aes.h>
#include <openssl/rsa.h>
#include <time.h>
#include <string>
#include <vector>
#include "oec_device_features.h"
#include "oemcrypto_types.h"
#include "pst_report.h"
namespace wvoec {
constexpr size_t kMaxTestRSAKeyLength = 2000; // Rough estimate.
constexpr size_t kMaxCoreProvRequest = 150; // Rough estimate.
// This structure will be signed to simulate a provisioning response from the
// server.
struct RSAPrivateKeyMessage {
uint8_t rsa_key[kMaxTestRSAKeyLength];
uint8_t rsa_key_iv[KEY_IV_SIZE];
size_t rsa_key_length;
uint8_t enc_message_key[kMaxTestRSAKeyLength];
size_t enc_message_key_length;
uint32_t nonce;
};
// Holds an encryption key and can encrypt a provisioning message. It also can
// encrypt short buffers using CBC, such as content keys in a license.
class Encryptor {
public:
Encryptor() : enc_key_(KEY_SIZE, 0) {}
Encryptor(const std::vector<uint8_t>& enc_key) { set_enc_key(enc_key); };
Encryptor& operator=(const Encryptor&) = default;
void set_enc_key(const std::vector<uint8_t>& enc_key);
// This encrypts an RSAPrivateKeyMessage with encryption_key so that it may be
// loaded with OEMCrypto_LoadProvisioningResponse.
// This modifies the clear data: it adds padding and generates a random iv.
void PadAndEncryptProvisioningMessage(RSAPrivateKeyMessage* data,
RSAPrivateKeyMessage* encrypted) const;
void CBCEncrypt(const uint8_t* data, uint8_t* encrypted_data,
size_t data_length, const uint8_t (&iv)[KEY_IV_SIZE]) const;
private:
std::vector<uint8_t> enc_key_;
};
// Holds encryption and mac keys derived from a master key.
// Can be used to sign a buffer as either a server or client.
class KeyDeriver : public Encryptor {
public:
KeyDeriver()
: mac_key_server_(MAC_KEY_SIZE, 0), mac_key_client_(MAC_KEY_SIZE, 0) {}
KeyDeriver& operator=(const KeyDeriver&) = default;
// Generate mac and enc keys give the master key.
void DeriveKeys(const uint8_t* master_key,
const std::vector<uint8_t>& mac_key_context,
const std::vector<uint8_t>& enc_key_context);
// Sign the buffer with server's mac key.
void ServerSignBuffer(const uint8_t* data, size_t data_length,
std::vector<uint8_t>* signature) const;
// Sign the buffer with client's known mac key. Known test keys must be
// installed first. This uses HMAC with SHA256, so is suitable for a message.
void ClientSignBuffer(const std::vector<uint8_t>& buffer,
std::vector<uint8_t>* signature) const;
// Sign the pst buffer with client's known mac key. Known test keys must be
// installed first. This uses HMAC with SHA128, and skips the beginning of the
// buffer, so is only suitable for a pst report.
void ClientSignPstReport(const std::vector<uint8_t>& pst_report_buffer,
std::vector<uint8_t>* signature) const;
void set_mac_keys(const uint8_t* mac_keys);
private:
// Internal utility function to derive key using CMAC-128
void DeriveKey(const uint8_t* key, const std::vector<uint8_t>& context,
int counter, std::vector<uint8_t>* out);
std::vector<uint8_t> mac_key_server_;
std::vector<uint8_t> mac_key_client_;
};
} // namespace wvoec
#endif // CDM_OEC_KEY_DERIVER_H_