From 183aacf0a3054a78364441f2b1f8243909fb4bf5 Mon Sep 17 00:00:00 2001 From: Gene Morgan Date: Fri, 1 Sep 2017 14:17:56 -0700 Subject: [PATCH] Source release v3.4.1 --- CHANGELOG.md | 13 + README.txt | 4 +- ...idevine_CE_CDM_IntegrationGuide_v3.4.x.pdf | Bin 386364 -> 389025 bytes cdm/cdm.gyp | 7 - cdm/include/cdm.h | 7 + cdm/include/cdm_version.h | 2 +- cdm/src/cdm.cpp | 36 + cdm/test/cdm_test_main.cpp | 1 + core/include/crypto_key.h | 15 + core/include/crypto_session.h | 49 +- core/include/initialization_data.h | 2 + core/include/license.h | 7 + core/include/policy_engine.h | 2 + core/include/properties.h | 1 + core/include/wv_cdm_types.h | 8 + core/src/cdm_session.cpp | 13 + core/src/crypto_session.cpp | 784 ++++++++++++++---- core/src/initialization_data.cpp | 31 +- core/src/license.cpp | 129 ++- core/src/license_protocol.proto | 61 +- core/src/oemcrypto_adapter_static_v12.cpp | 19 +- core/src/policy_engine.cpp | 8 + core/src/string_conversions.cpp | 171 ++-- core/test/base64_test.cpp | 13 + core/test/initialization_data_unittest.cpp | 74 +- core/test/license_unittest.cpp | 128 ++- core/test/test_printers.cpp | 21 + oemcrypto/include/OEMCryptoCENC.h | 14 +- oemcrypto/test/oec_session_util.h | 1 + oemcrypto/test/oemcrypto_test.cpp | 67 +- platforms/x86-64/settings.gypi | 53 +- third_party/gmock.gyp | 16 + third_party/gyp/common.py | 2 + third_party/gyp/easy_xml.py | 5 + third_party/gyp/generator/make.py | 30 +- third_party/gyp/generator/msvs.py | 16 +- third_party/gyp/generator/ninja.py | 15 +- third_party/gyp/mac_tool.py | 14 +- third_party/protobuf.gypi | 11 + third_party/stringencoders/LICENSE | 22 - third_party/stringencoders/src/config.h | 0 .../stringencoders/src/extern_c_begin.h | 3 - third_party/stringencoders/src/extern_c_end.h | 3 - third_party/stringencoders/src/modp_b64.cpp | 254 ------ third_party/stringencoders/src/modp_b64.h | 236 ------ .../stringencoders/src/modp_b64_data.h | 477 ----------- third_party/stringencoders/src/modp_b64w.cpp | 254 ------ third_party/stringencoders/src/modp_b64w.h | 231 ------ .../stringencoders/src/modp_b64w_data.h | 477 ----------- third_party/stringencoders/src/modp_stdint.h | 43 - 50 files changed, 1508 insertions(+), 2342 deletions(-) rename Widevine_CE_CDM_IntegrationGuide_v3.3.x.pdf => Widevine_CE_CDM_IntegrationGuide_v3.4.x.pdf (65%) delete mode 100644 third_party/stringencoders/LICENSE delete mode 100644 third_party/stringencoders/src/config.h delete mode 100644 third_party/stringencoders/src/extern_c_begin.h delete mode 100644 third_party/stringencoders/src/extern_c_end.h delete mode 100644 third_party/stringencoders/src/modp_b64.cpp delete mode 100644 third_party/stringencoders/src/modp_b64.h delete mode 100644 third_party/stringencoders/src/modp_b64_data.h delete mode 100644 third_party/stringencoders/src/modp_b64w.cpp delete mode 100644 third_party/stringencoders/src/modp_b64w.h delete mode 100644 third_party/stringencoders/src/modp_b64w_data.h delete mode 100644 third_party/stringencoders/src/modp_stdint.h diff --git a/CHANGELOG.md b/CHANGELOG.md index a0026863..d01fd129 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +## 3.4.0 (2017-08-31) + +Features: + - Preliminary support for sublicenses and key rotation using sublicenses. + +BugFixes: + - Fixed build failure in protobuf host tools build (relaxed compiler + warning checks). + - Enabled a number of more restrictive compiler checks, and fixed + non-compliant code. + - Mock OEMCrypto: handle case of non-aligned nonce pointer in + OEMCrypto_RewrapDeviceRSAKey() and OEMCrypto_RewrapDevideRSAKey30() + ## 3.3.0 (2017-05-03) Features: diff --git a/README.txt b/README.txt index bc404a1f..389fbf71 100644 --- a/README.txt +++ b/README.txt @@ -1,4 +1,4 @@ -README for Widevine CE_CDM v3.3.x - 3 May, 2017 +README for Widevine CE_CDM v3.4.x - 31 August, 2017 Getting started @@ -7,7 +7,7 @@ This project contains the sources for building a Widevine CDM module. Read the following to learn more about the contents of this project and how to use them: -Widevine_CE_CDM_IntegrationGuide_v3.3.x.pdf +Widevine_CE_CDM_IntegrationGuide_v3.4.x.pdf Documents the CDM API and describes how to integrate the CDM into a system. diff --git a/Widevine_CE_CDM_IntegrationGuide_v3.3.x.pdf b/Widevine_CE_CDM_IntegrationGuide_v3.4.x.pdf similarity index 65% rename from Widevine_CE_CDM_IntegrationGuide_v3.3.x.pdf rename to Widevine_CE_CDM_IntegrationGuide_v3.4.x.pdf index 0a389092c6eea30203d2915afefcce26dc808191..941a5a38d718e5ed8678bc2a9fbd47bdd7c059bf 100644 GIT binary patch delta 129008 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

lQv*-RWNqM}|Kga;#@?%>%8?L%c`JbX9!7 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

s*u($i&H8-E(ed`>y!o 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

3A$R_4kUT(cvN_0vsrsWF`AnS;(g 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 diff --git a/cdm/cdm.gyp b/cdm/cdm.gyp index 4ee30331..cdb86b13 100644 --- a/cdm/cdm.gyp +++ b/cdm/cdm.gyp @@ -88,7 +88,6 @@ '../core/include', '../oemcrypto/include', '../third_party/jsmn', - '../third_party/stringencoders/src', ], 'direct_dependent_settings': { 'include_dirs': [ @@ -141,12 +140,6 @@ '../core/src/string_conversions.cpp', '../third_party/jsmn/jsmn.h', '../third_party/jsmn/jsmn.c', - '../third_party/stringencoders/src/modp_b64_data.h', - '../third_party/stringencoders/src/modp_b64.cpp', - '../third_party/stringencoders/src/modp_b64.h', - '../third_party/stringencoders/src/modp_b64w_data.h', - '../third_party/stringencoders/src/modp_b64w.cpp', - '../third_party/stringencoders/src/modp_b64w.h', ], 'conditions': [ ['oemcrypto_version < 9', { diff --git a/cdm/include/cdm.h b/cdm/include/cdm.h index 877e406f..4993c9e9 100644 --- a/cdm/include/cdm.h +++ b/cdm/include/cdm.h @@ -61,6 +61,8 @@ class CDM_EXPORT Cdm : public ITimerClient { kLicenseRelease = 2, kIndividualizationRequest = 3, // Not used. Direct Individualization // is used instead of App-Assisted + kLicenseSub = 4 // Used in loading sub licenses from + // embedded key data. } MessageType; // Status codes returned by CDM functions. @@ -421,6 +423,11 @@ class CDM_EXPORT Cdm : public ITimerClient { // Loads an existing persisted session from storage. virtual Status load(const std::string& session_id) = 0; + // Loads a new sublicense as specified in init_data. + virtual Status load(const std::string& session_id, + InitDataType init_data_type, + const std::string& init_data) = 0; + // Provides messages, including licenses, to the CDM. // If the message is a successful response to a release message, stored // session data will be removed for the session. diff --git a/cdm/include/cdm_version.h b/cdm/include/cdm_version.h index d70bba54..7f9fa78b 100644 --- a/cdm/include/cdm_version.h +++ b/cdm/include/cdm_version.h @@ -1,2 +1,2 @@ // Widevine CE CDM Version -#define CDM_VERSION "v3.3.0-0-gffcfda19-ce" +#define CDM_VERSION "v3.4.1-0-gb429ebdf-ce" diff --git a/cdm/src/cdm.cpp b/cdm/src/cdm.cpp index 0ff2063d..a1c0e073 100644 --- a/cdm/src/cdm.cpp +++ b/cdm/src/cdm.cpp @@ -146,6 +146,10 @@ class CdmImpl : public Cdm, virtual Status load(const std::string& session_id) OVERRIDE; + virtual Status load(const std::string& session_id, + InitDataType init_data_type, + const std::string& init_data) OVERRIDE; + virtual Status update(const std::string& session_id, const std::string& response) OVERRIDE; @@ -613,6 +617,38 @@ Cdm::Status CdmImpl::load(const std::string& session_id) { return kSuccess; } +Cdm::Status CdmImpl::load(const std::string& session_id, + InitDataType init_data_type, + const std::string& init_data) { + if (!cdm_engine_.IsOpenSession(session_id)) { + LOGE("Session %s does not exist.", session_id.c_str()); + return kSessionNotFound; + } + + if (init_data_type != kCenc) { + LOGE("Invalid init data type: %d", init_data_type); + return kTypeError; + } + + InitializationData init_data_obj(CENC_INIT_DATA_FORMAT, init_data); + if (init_data_obj.IsEmpty()) { + // Note that InitializationData's idea of "empty" includes "failed to find + // and parse a Widevine PSSH". This should not happen for WebM init data, + // which requires no parsing. + LOGE("Failed to parse init data, may not contain a Widevine PSSH."); + return kNotSupported; + } + + CdmKeyRequest key_request; + CdmResponseType result = cdm_engine_.GenerateKeyRequest( + session_id, session_id, init_data_obj, kLicenseTypeSubSession, + app_parameters_, &key_request); + if (result != KEY_MESSAGE) { + return kUnexpectedError; + } + return kSuccess; +} + Cdm::Status CdmImpl::update(const std::string& session_id, const std::string& response) { if (provision_request_sent_) { diff --git a/cdm/test/cdm_test_main.cpp b/cdm/test/cdm_test_main.cpp index 6d10571b..2ee5e45a 100644 --- a/cdm/test/cdm_test_main.cpp +++ b/cdm/test/cdm_test_main.cpp @@ -76,6 +76,7 @@ int main(int argc, char** argv) { #if defined(OEMCRYPTO_TESTS) // Set up the OEMCrypto test harness. + // NOTE: This creates a temporary OEMCrypto "instance". wvoec::global_features.Initialize(false /* is_cast_receiver */, false /* force_load_test_keybox */); ::testing::GTEST_FLAG(filter) diff --git a/core/include/crypto_key.h b/core/include/crypto_key.h index 921517e6..0da57d56 100644 --- a/core/include/crypto_key.h +++ b/core/include/crypto_key.h @@ -17,6 +17,9 @@ class CryptoKey { const std::string& key_data_iv() const { return key_data_iv_; } const std::string& key_control() const { return key_control_; } const std::string& key_control_iv() const { return key_control_iv_; } + const std::string& sub_session_key_id() const {return sub_session_key_id_;} + const std::string& sub_session_key() const {return sub_session_key_;} + const std::string& track_label() const { return track_label_; } CdmCipherMode cipher_mode() const { return cipher_mode_; } void set_key_id(const std::string& key_id) { key_id_ = key_id; } void set_key_data(const std::string& key_data) { key_data_ = key_data; } @@ -28,6 +31,15 @@ class CryptoKey { void set_cipher_mode(CdmCipherMode cipher_mode) { cipher_mode_ = cipher_mode; } + void set_sub_session_key_id(const std::string& sub_session_key_id) { + sub_session_key_id_ = sub_session_key_id; + } + void set_sub_session_key(const std::string& sub_session_key) { + sub_session_key_ = sub_session_key; + } + void set_track_label(const std::string& track_label) { + track_label_ = track_label; + } bool HasKeyControl() const { return key_control_.size() >= 16; } @@ -37,6 +49,9 @@ class CryptoKey { std::string key_data_; std::string key_control_; std::string key_control_iv_; + std::string sub_session_key_id_; + std::string track_label_; + std::string sub_session_key_; CdmCipherMode cipher_mode_; }; diff --git a/core/include/crypto_session.h b/core/include/crypto_session.h index 181b90bc..89ee4943 100644 --- a/core/include/crypto_session.h +++ b/core/include/crypto_session.h @@ -10,12 +10,39 @@ #include "lock.h" #include "oemcrypto_adapter.h" #include "OEMCryptoCENC.h" +#include "scoped_ptr.h" #include "wv_cdm_types.h" namespace wvcdm { class CryptoKey; typedef std::map CryptoKeyMap; +typedef std::map SubLicenseSessionMap; + +class KeySession { + protected: + KeySession() {} + + public: + typedef enum { kDefault, kSubLicense } KeySessionType; + virtual ~KeySession() {} + virtual KeySessionType Type() = 0; + virtual bool GenerateDerivedKeys(const std::string& message) = 0; + virtual bool GenerateDerivedKeys(const std::string& message, + const std::string& session_key) = 0; + virtual OEMCryptoResult LoadKeys(const std::string& message, + const std::string& signature, + const std::string& mac_key_iv, + const std::string& mac_key, + const std::vector& keys, + const std::string& provider_session_token, + CdmCipherMode* cipher_mode) = 0; + virtual OEMCryptoResult SelectKey(const std::string& key_id) = 0; + virtual OEMCryptoResult Decrypt( + const CdmDecryptionParameters& params, + OEMCrypto_DestBufferDesc& buffer_descriptor, + OEMCrypto_CENCEncryptPatternDesc& pattern_descriptor) = 0; +}; class CryptoSession { public: @@ -79,7 +106,7 @@ class CryptoSession { std::string* wrapped_private_key); // Media data path - virtual CdmResponseType Decrypt(const CdmDecryptionParameters& parameters); + virtual CdmResponseType Decrypt(const CdmDecryptionParameters& params); // Usage related methods virtual bool UsageInformationSupport(bool* has_support); @@ -129,19 +156,21 @@ class CryptoSession { CdmSigningAlgorithm algorithm, const std::string& signature); + virtual CdmResponseType AddSubSession(const std::string& sub_session_key_id); + // TODO(jfore): exists is set based on whether a sub session exists. For now, + // that is not assumed to be an error. + virtual bool GenerateSubSessionNonce(const std::string& sub_session_key_id, + bool* exists, uint32_t* nonce); + private: bool GetProvisioningMethod(CdmClientTokenType& token_type); void Init(); void Terminate(); bool GetTokenFromKeybox(std::string* token); bool GetTokenFromOemCert(std::string* token); - void GenerateMacContext(const std::string& input_context, - std::string* deriv_context); - void GenerateEncryptContext(const std::string& input_context, - std::string* deriv_context); bool GenerateSignature(const std::string& message, std::string* signature); bool GenerateRsaSignature(const std::string& message, std::string* signature); - size_t GetOffset(std::string message, std::string field); + bool SetDestinationBufferType(); bool RewrapDeviceRSAKey( @@ -154,7 +183,7 @@ class CryptoSession { const std::string& private_key, const std::string& iv, const std::string& wrapping_key, std::string* wrapped_private_key); - bool SelectKey(const std::string& key_id); + CdmResponseType SelectKey(const std::string& key_id); static const OEMCrypto_Algorithm kInvalidAlgorithm = static_cast(-1); @@ -177,7 +206,7 @@ class CryptoSession { static void IncrementIV(uint64_t increase_by, std::vector* iv_out); static const size_t kAes128BlockSize = 16; // Block size for AES_CBC_128 - static const size_t kSignatureSize = 32; // size for HMAC-SHA256 signature + static const size_t kSignatureSize = 32; // size for HMAC-SHA256 signature static Lock crypto_lock_; static bool initialized_; static int session_count_; @@ -187,6 +216,10 @@ class CryptoSession { std::string oem_token_; // Cached OEMCrypto Public Key bool update_usage_table_after_close_session_; CryptoSessionId oec_session_id_; + SubLicenseSessionMap sub_license_oec_sessions_; + // Used for sub license sessions. + std::string wrapped_key_; + scoped_ptr key_session_; OEMCryptoBufferType destination_buffer_type_; bool is_destination_buffer_type_valid_; diff --git a/core/include/initialization_data.h b/core/include/initialization_data.h index c4edbd06..8a9b42af 100644 --- a/core/include/initialization_data.h +++ b/core/include/initialization_data.h @@ -5,6 +5,7 @@ #include +#include "license_protocol.pb.h" #include "wv_cdm_types.h" namespace wvcdm { @@ -27,6 +28,7 @@ class InitializationData { const CdmInitData& data() const { return data_; } std::vector hls_iv() const { return hls_iv_; } CdmHlsMethod hls_method() const { return hls_method_; } + std::vector ExtractEmbeddedKeys() const; private: // Parse a blob of multiple concatenated PSSH atoms to extract the first diff --git a/core/include/license.h b/core/include/license.h index 11fc062e..14d36797 100644 --- a/core/include/license.h +++ b/core/include/license.h @@ -21,6 +21,7 @@ class Clock; class CryptoSession; class PolicyEngine; class ServiceCertificate; +class CryptoKey; class CdmLicense { public: @@ -43,6 +44,7 @@ class CdmLicense { const CdmKeyResponse& license_response); virtual CdmResponseType HandleKeyUpdateResponse( bool is_renewal, const CdmKeyResponse& license_response); + virtual CdmResponseType HandleSubLicense(const InitializationData& init_data); virtual bool RestoreOfflineLicense( const CdmKeyMessage& license_request, @@ -107,6 +109,11 @@ class CdmLicense { // For testing // CdmLicense takes ownership of the clock. CdmLicense(const CdmSessionId& session_id, Clock* clock); + + // For sublicense key embedding. This key array will be initilized with any + // sub session keys we may have received in a license response. These keys + // may be used to support key rotation. + std::vector sub_session_key_array_; #if defined(UNIT_TEST) friend class CdmLicenseTest; #endif diff --git a/core/include/policy_engine.h b/core/include/policy_engine.h index 3b8d25ef..73daea13 100644 --- a/core/include/policy_engine.h +++ b/core/include/policy_engine.h @@ -50,6 +50,8 @@ class PolicyEngine { // permits playback. virtual void SetLicense(const video_widevine::License& license); + virtual void UpdateLicenseKeys(const video_widevine::License& license); + // SetLicenseForRelease is used when releasing a license. The keys in this // license will be ignored, and any old keys will be expired. virtual void SetLicenseForRelease( diff --git a/core/include/properties.h b/core/include/properties.h index af5e717d..9b14187d 100644 --- a/core/include/properties.h +++ b/core/include/properties.h @@ -109,6 +109,7 @@ class Properties { FRIEND_TEST(CdmSessionTest, InitFailCryptoError); FRIEND_TEST(CdmSessionTest, InitNeedsProvisioning); FRIEND_TEST(CdmLicenseTest, PrepareKeyRequestValidation); + FRIEND_TEST(SubLicenseTest, VerifySubSessionData); #endif private: diff --git a/core/include/wv_cdm_types.h b/core/include/wv_cdm_types.h index 684234f7..37fee292 100644 --- a/core/include/wv_cdm_types.h +++ b/core/include/wv_cdm_types.h @@ -271,6 +271,13 @@ enum CdmResponseType { PARSE_RESPONSE_ERROR_2, PARSE_RESPONSE_ERROR_3, /* 230 */ PARSE_RESPONSE_ERROR_4, + LICENSE_REQUEST_INVALID_SUBLICENSE, + INVALID_SESSION_1, + NO_DEVICE_KEY_1, + NO_CONTENT_KEY_2, /* 235 */ + INSUFFICIENT_CRYPTO_RESOURCES_2, + UNKNOWN_SELECT_KEY_ERROR_1, + UNKNOWN_SELECT_KEY_ERROR_2, }; enum CdmKeyStatus { @@ -294,6 +301,7 @@ enum CdmLicenseType { // Like Streaming, but stricter. Does not permit storage of any kind. // Named after the 'temporary' session type in EME, which has this behavior. kLicenseTypeTemporary, + kLicenseTypeSubSession }; enum SecurityLevel { diff --git a/core/src/cdm_session.cpp b/core/src/cdm_session.cpp index 2c10d5a0..ab8c97f8 100644 --- a/core/src/cdm_session.cpp +++ b/core/src/cdm_session.cpp @@ -243,6 +243,8 @@ CdmResponseType CdmSession::GenerateKeyRequest( case kLicenseTypeRelease: is_release_ = true; break; + case kLicenseTypeSubSession: + return license_parser_->HandleSubLicense(init_data); default: LOGE("CdmSession::GenerateKeyRequest: unrecognized license type: %ld", license_type); @@ -270,6 +272,17 @@ CdmResponseType CdmSession::GenerateKeyRequest( return KEY_REQUEST_ERROR_1; } + std::vector embedded_key_data = + init_data.ExtractEmbeddedKeys(); + for (int i = 0; i < embedded_key_data.size(); ++i) { + CdmResponseType sts = crypto_session_->AddSubSession( + embedded_key_data[i].sub_session_key_id()); + if (NO_ERROR != sts) { + LOGE("CdmSession::GenerateKeyRequest: Unable to generate sub session"); + return sts; + } + } + app_parameters_ = app_parameters; CdmResponseType status = license_parser_->PrepareKeyRequest( init_data, license_type, diff --git a/core/src/crypto_session.cpp b/core/src/crypto_session.cpp index 5a8684a5..9f736baa 100644 --- a/core/src/crypto_session.cpp +++ b/core/src/crypto_session.cpp @@ -26,6 +26,47 @@ std::string EncodeUint32(unsigned int u) { s.append(1, (u >> 0) & 0xFF); return s; } +size_t GetOffset(std::string message, std::string field) { + size_t pos = message.find(field); + if (pos == std::string::npos) { + LOGE("CryptoSession::GetOffset : Cannot find offset for %s", field.c_str()); + pos = 0; + } + return pos; +} +void GenerateMacContext(const std::string& input_context, + std::string* deriv_context) { + if (!deriv_context) { + LOGE("CryptoSession::GenerateMacContext : No output destination provided."); + return; + } + + const std::string kSigningKeyLabel = "AUTHENTICATION"; + const size_t kSigningKeySizeBits = wvcdm::MAC_KEY_SIZE * 8; + + deriv_context->assign(kSigningKeyLabel); + deriv_context->append(1, '\0'); + deriv_context->append(input_context); + deriv_context->append(EncodeUint32(kSigningKeySizeBits * 2)); +} + +void GenerateEncryptContext(const std::string& input_context, + std::string* deriv_context) { + if (!deriv_context) { + LOGE( + "CryptoSession::GenerateEncryptContext : No output destination " + "provided."); + return; + } + + const std::string kEncryptionKeyLabel = "ENCRYPTION"; + const size_t kEncryptionKeySizeBits = wvcdm::KEY_SIZE * 8; + + deriv_context->assign(kEncryptionKeyLabel); + deriv_context->append(1, '\0'); + deriv_context->append(input_context); + deriv_context->append(EncodeUint32(kEncryptionKeySizeBits)); +} const uint32_t kRsaSignatureLength = 256; const size_t kMaximumChunkSize = 100 * 1024; // 100 KiB } @@ -37,6 +78,464 @@ bool CryptoSession::initialized_ = false; int CryptoSession::session_count_ = 0; uint64_t CryptoSession::request_id_index_ = 0; +class DefaultKeySession : public KeySession { + public: + explicit DefaultKeySession(CryptoSessionId oec_session_id) + : oec_session_id_(oec_session_id) {} + virtual ~DefaultKeySession() {} + + KeySessionType Type() { return kDefault; } + bool GenerateDerivedKeys(const std::string& message) { + std::string mac_deriv_message; + std::string enc_deriv_message; + GenerateMacContext(message, &mac_deriv_message); + GenerateEncryptContext(message, &enc_deriv_message); + + LOGV("GenerateDerivedKeys: id=%ld", (uint32_t)oec_session_id_); + OEMCryptoResult sts = OEMCrypto_GenerateDerivedKeys( + oec_session_id_, + reinterpret_cast(mac_deriv_message.data()), + mac_deriv_message.size(), + reinterpret_cast(enc_deriv_message.data()), + enc_deriv_message.size()); + if (OEMCrypto_SUCCESS != sts) { + LOGE("GenerateDerivedKeys: OEMCrypto_GenerateDerivedKeys error=%d", sts); + return false; + } + + return true; + } + + bool GenerateDerivedKeys(const std::string& message, + const std::string& session_key) { + std::string mac_deriv_message; + std::string enc_deriv_message; + GenerateMacContext(message, &mac_deriv_message); + GenerateEncryptContext(message, &enc_deriv_message); + + LOGV("GenerateDerivedKeys: id=%ld", (uint32_t)oec_session_id_); + OEMCryptoResult sts = OEMCrypto_DeriveKeysFromSessionKey( + oec_session_id_, + reinterpret_cast(session_key.data()), + session_key.size(), + reinterpret_cast(mac_deriv_message.data()), + mac_deriv_message.size(), + reinterpret_cast(enc_deriv_message.data()), + enc_deriv_message.size()); + if (OEMCrypto_SUCCESS != sts) { + LOGE("GenerateDerivedKeys: OEMCrypto_DeriveKeysFromSessionKey err=%d", + sts); + return false; + } + + return true; + } + + OEMCryptoResult LoadKeys(const std::string& message, + const std::string& signature, + const std::string& mac_key_iv, + const std::string& mac_key, + const std::vector& keys, + const std::string& provider_session_token, + CdmCipherMode* cipher_mode) { + const uint8_t* msg = reinterpret_cast(message.data()); + const uint8_t* enc_mac_key = NULL; + const uint8_t* enc_mac_key_iv = NULL; + if (mac_key.size() >= MAC_KEY_SIZE && mac_key_iv.size() >= KEY_IV_SIZE) { + enc_mac_key = msg + GetOffset(message, mac_key); + enc_mac_key_iv = msg + GetOffset(message, mac_key_iv); + } else { + LOGV("CryptoSession::LoadKeys: enc_mac_key not set"); + } + std::vector load_keys(keys.size()); + for (size_t i = 0; i < keys.size(); ++i) { + const CryptoKey* ki = &keys[i]; + OEMCrypto_KeyObject* ko = &load_keys[i]; + ko->key_id = msg + GetOffset(message, ki->key_id()); + ko->key_id_length = ki->key_id().length(); + ko->key_data_iv = msg + GetOffset(message, ki->key_data_iv()); + ko->key_data = msg + GetOffset(message, ki->key_data()); + ko->key_data_length = ki->key_data().length(); + if (ki->HasKeyControl()) { + ko->key_control_iv = msg + GetOffset(message, ki->key_control_iv()); + ko->key_control = msg + GetOffset(message, ki->key_control()); + } else { + LOGE("For key %d: XXX key has no control block. size=%d", i, + ki->key_control().size()); + ko->key_control_iv = NULL; + ko->key_control = NULL; + } + ko->cipher_mode = ki->cipher_mode() == kCipherModeCbc + ? OEMCrypto_CipherMode_CBC + : OEMCrypto_CipherMode_CTR; + *cipher_mode = ki->cipher_mode(); + } + uint8_t* pst = NULL; + if (!provider_session_token.empty()) { + pst = const_cast(msg) + + GetOffset(message, provider_session_token); + } + + LOGV("LoadKeys: id=%ld", (uint32_t)oec_session_id_); + return OEMCrypto_LoadKeys( + oec_session_id_, msg, message.size(), + reinterpret_cast(signature.data()), + signature.size(), enc_mac_key_iv, enc_mac_key, keys.size(), + &load_keys[0], pst, provider_session_token.length()); + } + + OEMCryptoResult SelectKey(const std::string& key_id) { + // Crypto session lock already locked. + if (!cached_key_id_.empty() && cached_key_id_ == key_id) { + // Already using the desired key. + return OEMCrypto_SUCCESS; + } + + cached_key_id_ = key_id; + + const uint8_t* key_id_string = + reinterpret_cast(cached_key_id_.data()); + + OEMCryptoResult sts = OEMCrypto_SelectKey(oec_session_id_, key_id_string, + cached_key_id_.size()); + + if (OEMCrypto_SUCCESS != sts) { + cached_key_id_.clear(); + } + return sts; + } + + OEMCryptoResult Decrypt( + const CdmDecryptionParameters& params, + OEMCrypto_DestBufferDesc& buffer_descriptor, + OEMCrypto_CENCEncryptPatternDesc& pattern_descriptor) { + + return OEMCrypto_DecryptCENC( + oec_session_id_, params.encrypt_buffer, params.encrypt_length, + params.is_encrypted, &(*params.iv).front(), params.block_offset, + &buffer_descriptor, &pattern_descriptor, params.subsample_flags); + } + + private: + CryptoSessionId oec_session_id_; + KeyId cached_key_id_; +}; + +// TODO(jfore): Move this class into it's own module. +class SubLicenseKeySession : public KeySession { + typedef enum { + kInitializing, + kInitialLicenseLoaded, + kInitialLicenseFailed, + } SubLicenseState; + + public: + SubLicenseKeySession(SubLicenseSessionMap& sub_license_oec_sessions, + std::string& wrapped_private_device_key, + SecurityLevel requested_security_level) + : state_(kInitializing), + wrapped_private_device_key_(wrapped_private_device_key), + sub_license_oec_sessions_(sub_license_oec_sessions), + requested_security_level_(requested_security_level) {} + virtual ~SubLicenseKeySession() {} + + KeySessionType Type() { return kSubLicense; } + // This version of GenerateDerivedKeys is for devices using keyboxes. It is + // not supported using sub licenses. + bool GenerateDerivedKeys(const std::string& message) { + return false; + } + + // GenerateDerivedKeys is called for each open oemcrypto session and is only + // called once. + bool GenerateDerivedKeys(const std::string& message, + const std::string& session_key) { + std::string mac_deriv_message; + std::string enc_deriv_message; + GenerateMacContext(message, &mac_deriv_message); + GenerateEncryptContext(message, &enc_deriv_message); + + for (SubLicenseSessionMap::iterator it = sub_license_oec_sessions_.begin(); + it != sub_license_oec_sessions_.end(); it++) { + LOGV("GenerateDerivedKeys: id=%ld", (uint32_t)it->second); + OEMCryptoResult sts = OEMCrypto_DeriveKeysFromSessionKey( + it->second, reinterpret_cast(session_key.data()), + session_key.size(), + reinterpret_cast(mac_deriv_message.data()), + mac_deriv_message.size(), + reinterpret_cast(enc_deriv_message.data()), + enc_deriv_message.size()); + + if (OEMCrypto_SUCCESS != sts) { + LOGE("GenerateDerivedKeys: OEMCrypto_DeriveKeysFromSessionKey err=%d", + sts); + return false; + } + } + + return true; + } + + // Load the keys in |keys|. The initial keys are saved for key rotation. + OEMCryptoResult LoadKeys(const std::string& message, + const std::string& signature, + const std::string& mac_key_iv, + const std::string& mac_key, + const std::vector& keys, + const std::string& provider_session_token, + CdmCipherMode* cipher_mode) { + if (state_ == kInitializing) { + state_ = kInitialLicenseLoaded; + keys_ = keys; + OEMCryptoResult sts = DoLoadKeys(message, + signature, + mac_key_iv, + mac_key, + keys, + provider_session_token, + cipher_mode); + if (OEMCrypto_SUCCESS != sts) { + state_ = kInitialLicenseFailed; + } + return sts; + } + return DoSubLicenseLoadKeys(message, signature, mac_key_iv, mac_key, + keys[0], provider_session_token, + cipher_mode); + } + + // Each oemcrypto session contains a single key. Find the right sub session + // and save it's id as the selected oemcrypto session. + OEMCryptoResult SelectKey(const std::string& key_id) { + for (int i = 0; i < keys_.size(); ++i) { + if (keys_[i].key_id() == key_id) { + cached_sub_session_key_id_ = keys_[i].sub_session_key_id(); + } + } + return OEMCrypto_SUCCESS; + } + + // Decrypt performs the decryption using the selected oemcrypto session. + // TODO(jfore): Support DecryptInChunks. + OEMCryptoResult Decrypt( + const CdmDecryptionParameters& params, + OEMCrypto_DestBufferDesc& buffer_descriptor, + OEMCrypto_CENCEncryptPatternDesc& pattern_descriptor) { + SubLicenseSessionMap::iterator it = + sub_license_oec_sessions_.find(cached_sub_session_key_id_); + if (it == sub_license_oec_sessions_.end()) { + return OEMCrypto_ERROR_INVALID_SESSION; + } + + return OEMCrypto_DecryptCENC( + it->second, params.encrypt_buffer, params.encrypt_length, + params.is_encrypted, &(*params.iv).front(), params.block_offset, + &buffer_descriptor, &pattern_descriptor, params.subsample_flags); + } + + private: + // Destroy each open oemcrypto session and relace them with new ones. + OEMCryptoResult ResetCryptoSessions() { + for (SubLicenseSessionMap::iterator it = sub_license_oec_sessions_.begin(); + it != sub_license_oec_sessions_.end(); it++) { + OEMCryptoResult sts; + sts = OEMCrypto_CloseSession(it->second); + if (OEMCrypto_SUCCESS != sts) { + return sts; + } + sts = OEMCrypto_OpenSession(&it->second, requested_security_level_); + if (OEMCrypto_SUCCESS != sts) { + return sts; + } + sts = OEMCrypto_LoadDeviceRSAKey( + it->second, + reinterpret_cast(wrapped_private_device_key_.data()), + wrapped_private_device_key_.size()); + if (OEMCrypto_SUCCESS != sts) { + return sts; + } + } + return OEMCrypto_SUCCESS; + } + + // DoLoadKeys loads a single key into each oemcrypto session. + OEMCryptoResult DoLoadKeys(const std::string& message, + const std::string& signature, + const std::string& mac_key_iv, + const std::string& mac_key, + const std::vector& keys, + const std::string& provider_session_token, + CdmCipherMode* cipher_mode) { + const uint8_t* msg = reinterpret_cast(message.data()); + const uint8_t* enc_mac_key = NULL; + const uint8_t* enc_mac_key_iv = NULL; + if (mac_key.size() >= MAC_KEY_SIZE && mac_key_iv.size() >= KEY_IV_SIZE) { + enc_mac_key = msg + GetOffset(message, mac_key); + enc_mac_key_iv = msg + GetOffset(message, mac_key_iv); + } else { + LOGV("CryptoSession::LoadKeys: enc_mac_key not set"); + } + uint8_t* pst = NULL; + if (!provider_session_token.empty()) { + pst = const_cast(msg) + + GetOffset(message, provider_session_token); + } + + // TODO(jfore): Use C++ 11 range loop? + for (int i = 0; i < keys.size(); i++) { + OEMCrypto_KeyObject key_object; + const CryptoKey& key_data = keys[i]; + key_object.key_id = msg + GetOffset(message, key_data.key_id()); + key_object.key_id_length = key_data.key_id().length(); + key_object.key_data_iv = msg + GetOffset(message, key_data.key_data_iv()); + key_object.key_data = msg + GetOffset(message, key_data.key_data()); + key_object.key_data_length = key_data.key_data().length(); + if (key_data.HasKeyControl()) { + key_object.key_control_iv = + msg + GetOffset(message, key_data.key_control_iv()); + key_object.key_control = + msg + GetOffset(message, key_data.key_control()); + } else { + LOGE("For key %s: XXX key has no control block. size=%d", + key_data.key_id().c_str(), key_data.key_control().size()); + key_object.key_control_iv = NULL; + key_object.key_control = NULL; + } + key_object.cipher_mode = key_data.cipher_mode() == kCipherModeCbc + ? OEMCrypto_CipherMode_CBC + : OEMCrypto_CipherMode_CTR; + *cipher_mode = key_data.cipher_mode(); + SubLicenseSessionMap::iterator oec_session_id = + sub_license_oec_sessions_.find(key_data.sub_session_key_id()); + if (oec_session_id == sub_license_oec_sessions_.end()) { + LOGE("CryptoSession::LoadKeys: Unrecognized sub session %s", + key_data.sub_session_key_id().c_str()); + return OEMCrypto_ERROR_INVALID_SESSION; + } + + OEMCryptoResult sts; + sts = OEMCrypto_LoadKeys( + oec_session_id->second, msg, message.size(), + reinterpret_cast(signature.data()), + signature.size(), enc_mac_key_iv, enc_mac_key, 1, &key_object, + pst, provider_session_token.length()); + if (sts != OEMCrypto_SUCCESS) { + return sts; + } + + sts = OEMCrypto_SelectKey( + oec_session_id->second, + reinterpret_cast(key_data.key_id().data()), + key_data.key_id().size()); + } + keys_ = keys; + return OEMCrypto_SUCCESS; + } + + // DoLoadKeys loads a single key into each oemcrypto session. + OEMCryptoResult DoSubLicenseLoadKeys( + const std::string& message, const std::string& signature, + const std::string& mac_key_iv, const std::string& mac_key, + const CryptoKey& key, const std::string& provider_session_token, + CdmCipherMode* cipher_mode) { + SubLicenseSessionMap::iterator it = sub_license_oec_sessions_.end(); + int key_index = 0; + for (; key_index < keys_.size(); key_index++) { + if (keys_[key_index].track_label() == key.track_label()) { + it = sub_license_oec_sessions_.find( + keys_[key_index].sub_session_key_id()); + CryptoKey tmp = key; + tmp.set_sub_session_key_id(keys_[key_index].sub_session_key_id()); + tmp.set_sub_session_key(keys_[key_index].sub_session_key()); + keys_[key_index] = tmp; + break; + } + } + if (it == sub_license_oec_sessions_.end()) { + return OEMCrypto_ERROR_INVALID_SESSION; + } + LOGV("GenerateDerivedKeys: id=%ld", (uint32_t)it->second); + + std::string mac_deriv_message; + std::string enc_deriv_message; + GenerateMacContext(key.track_label(), &mac_deriv_message); + GenerateEncryptContext(key.track_label(), &enc_deriv_message); + + const uint8_t* msg = reinterpret_cast(message.data()); + const uint8_t* enc_mac_key = NULL; + const uint8_t* enc_mac_key_iv = NULL; + if (mac_key.size() >= MAC_KEY_SIZE && mac_key_iv.size() >= KEY_IV_SIZE) { + enc_mac_key = msg + GetOffset(message, mac_key); + enc_mac_key_iv = msg + GetOffset(message, mac_key_iv); + } else { + LOGV("CryptoSession::LoadKeys: enc_mac_key not set"); + } + uint8_t* pst = NULL; + if (!provider_session_token.empty()) { + pst = const_cast(msg) + + GetOffset(message, provider_session_token); + } + + OEMCryptoResult sts; + const std::string& sub_session_key = keys_[key_index].sub_session_key(); + LOGE("ssksize = %d", sub_session_key.size()); + sts = OEMCrypto_DeriveKeysFromSessionKey( + it->second, reinterpret_cast(sub_session_key.data()), + sub_session_key.size(), + reinterpret_cast(mac_deriv_message.data()), + mac_deriv_message.size(), + reinterpret_cast(enc_deriv_message.data()), + enc_deriv_message.size()); + + if (OEMCrypto_SUCCESS != sts) { + LOGE("GenerateDerivedKeys: OEMCrypto_DeriveKeysFromSessionKey err=%d", + sts); + return sts; + } + + OEMCrypto_KeyObject key_object; + key_object.key_id = msg + GetOffset(message, keys_[key_index].key_id()); + key_object.key_id_length = keys_[key_index].key_id().length(); + key_object.key_data_iv = msg + GetOffset( + message, keys_[key_index].key_data_iv()); + key_object.key_data = msg + GetOffset(message, keys_[key_index].key_data()); + key_object.key_data_length = keys_[key_index].key_data().length(); + if (key.HasKeyControl()) { + key_object.key_control_iv = + msg + GetOffset(message, keys_[key_index].key_control_iv()); + key_object.key_control = msg + GetOffset( + message, keys_[key_index].key_control()); + } + key_object.cipher_mode = keys_[key_index].cipher_mode() == kCipherModeCbc + ? OEMCrypto_CipherMode_CBC + : OEMCrypto_CipherMode_CTR; + + sts = OEMCrypto_LoadKeys( + it->second, msg, message.size(), + reinterpret_cast(signature.data()), + signature.size(), enc_mac_key_iv, enc_mac_key, 1, &key_object, + pst, provider_session_token.length()); + if (sts != OEMCrypto_SUCCESS) { + return sts; + } + + sts = OEMCrypto_SelectKey( + it->second, + reinterpret_cast(keys_[key_index].key_id().data()), + keys_[key_index].key_id().size()); + return sts; + } + + SubLicenseState state_; + std::string cached_sub_session_key_id_; + std::string wrapped_private_device_key_; + std::string message_; + std::string session_key_; + std::vector keys_; + SubLicenseSessionMap& sub_license_oec_sessions_; + SecurityLevel requested_security_level_; +}; + CryptoSession::CryptoSession() : open_(false), update_usage_table_after_close_session_(false), @@ -349,6 +848,7 @@ CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) { OEMCrypto_GetRandom(reinterpret_cast(&request_id_base_), sizeof(request_id_base_)); ++request_id_index_; + key_session_.reset(new DefaultKeySession(oec_session_id_)); return NO_ERROR; } @@ -424,49 +924,6 @@ bool CryptoSession::PrepareRenewalRequest(const std::string& message, return true; } -void CryptoSession::GenerateMacContext(const std::string& input_context, - std::string* deriv_context) { - if (!deriv_context) { - LOGE("CryptoSession::GenerateMacContext : No output destination provided."); - return; - } - - const std::string kSigningKeyLabel = "AUTHENTICATION"; - const size_t kSigningKeySizeBits = MAC_KEY_SIZE * 8; - - deriv_context->assign(kSigningKeyLabel); - deriv_context->append(1, '\0'); - deriv_context->append(input_context); - deriv_context->append(EncodeUint32(kSigningKeySizeBits * 2)); -} - -void CryptoSession::GenerateEncryptContext(const std::string& input_context, - std::string* deriv_context) { - if (!deriv_context) { - LOGE( - "CryptoSession::GenerateEncryptContext : No output destination " - "provided."); - return; - } - - const std::string kEncryptionKeyLabel = "ENCRYPTION"; - const size_t kEncryptionKeySizeBits = KEY_SIZE * 8; - - deriv_context->assign(kEncryptionKeyLabel); - deriv_context->append(1, '\0'); - deriv_context->append(input_context); - deriv_context->append(EncodeUint32(kEncryptionKeySizeBits)); -} - -size_t CryptoSession::GetOffset(std::string message, std::string field) { - size_t pos = message.find(field); - if (pos == std::string::npos) { - LOGE("CryptoSession::GetOffset : Cannot find offset for %s", field.c_str()); - pos = 0; - } - return pos; -} - CdmResponseType CryptoSession::LoadKeys( const std::string& message, const std::string& signature, const std::string& mac_key_iv, const std::string& mac_key, @@ -475,49 +932,9 @@ CdmResponseType CryptoSession::LoadKeys( LOGV("CryptoSession::LoadKeys: Lock"); AutoLock auto_lock(crypto_lock_); - const uint8_t* msg = reinterpret_cast(message.data()); - const uint8_t* enc_mac_key = NULL; - const uint8_t* enc_mac_key_iv = NULL; - if (mac_key.size() >= MAC_KEY_SIZE && mac_key_iv.size() >= KEY_IV_SIZE) { - enc_mac_key = msg + GetOffset(message, mac_key); - enc_mac_key_iv = msg + GetOffset(message, mac_key_iv); - } else { - LOGV("CryptoSession::LoadKeys: enc_mac_key not set"); - } - std::vector load_keys(keys.size()); - for (size_t i = 0; i < keys.size(); ++i) { - const CryptoKey* ki = &keys[i]; - OEMCrypto_KeyObject* ko = &load_keys[i]; - ko->key_id = msg + GetOffset(message, ki->key_id()); - ko->key_id_length = ki->key_id().length(); - ko->key_data_iv = msg + GetOffset(message, ki->key_data_iv()); - ko->key_data = msg + GetOffset(message, ki->key_data()); - ko->key_data_length = ki->key_data().length(); - if (ki->HasKeyControl()) { - ko->key_control_iv = msg + GetOffset(message, ki->key_control_iv()); - ko->key_control = msg + GetOffset(message, ki->key_control()); - } else { - LOGE("For key %d: XXX key has no control block. size=%d", i, - ki->key_control().size()); - ko->key_control_iv = NULL; - ko->key_control = NULL; - } - ko->cipher_mode = ki->cipher_mode() == kCipherModeCbc - ? OEMCrypto_CipherMode_CBC - : OEMCrypto_CipherMode_CTR; - cipher_mode_ = ki->cipher_mode(); - } - uint8_t* pst = NULL; - if (!provider_session_token.empty()) { - pst = - const_cast(msg) + GetOffset(message, provider_session_token); - } - LOGV("LoadKeys: id=%ld", (uint32_t)oec_session_id_); - OEMCryptoResult sts = OEMCrypto_LoadKeys( - oec_session_id_, msg, message.size(), - reinterpret_cast(signature.data()), signature.size(), - enc_mac_key_iv, enc_mac_key, keys.size(), &load_keys[0], pst, - provider_session_token.length()); + OEMCryptoResult sts = key_session_->LoadKeys( + message, signature, mac_key_iv, mac_key, keys, provider_session_token, + &cipher_mode_); if (OEMCrypto_SUCCESS == sts) { if (!provider_session_token.empty()) { @@ -559,6 +976,7 @@ bool CryptoSession::LoadCertificatePrivateKey(std::string& wrapped_key) { LOGE("LoadCertificatePrivateKey: OEMCrypto_LoadDeviceRSAKey error=%d", sts); return false; } + wrapped_key_ = wrapped_key; return true; } @@ -592,79 +1010,47 @@ bool CryptoSession::RefreshKeys(const std::string& message, } } LOGV("RefreshKeys: id=%ld", static_cast(oec_session_id_)); - return ( - OEMCrypto_SUCCESS == - OEMCrypto_RefreshKeys(oec_session_id_, msg, message.size(), - reinterpret_cast(signature.data()), - signature.size(), num_keys, &load_key_array[0])); + OEMCryptoResult sts = OEMCrypto_RefreshKeys( + oec_session_id_, msg, message.size(), + reinterpret_cast(signature.data()), + signature.size(), num_keys, &load_key_array[0]); + return sts == OEMCrypto_SUCCESS; } -bool CryptoSession::SelectKey(const std::string& key_id) { - // Crypto session lock already locked. - if (!cached_key_id_.empty() && cached_key_id_ == key_id) { - // Already using the desired key. - return true; +CdmResponseType CryptoSession::SelectKey(const std::string& key_id) { + OEMCryptoResult sts = key_session_->SelectKey(key_id); + + switch (sts) { + case OEMCrypto_SUCCESS: + return NO_ERROR; + case OEMCrypto_ERROR_KEY_EXPIRED: + return NEED_KEY; + case OEMCrypto_ERROR_INSUFFICIENT_HDCP: + return INSUFFICIENT_OUTPUT_PROTECTION; + case OEMCrypto_ERROR_INVALID_SESSION: + return INVALID_SESSION_1; + case OEMCrypto_ERROR_NO_DEVICE_KEY: + return NO_DEVICE_KEY_1; + case OEMCrypto_ERROR_NO_CONTENT_KEY: + return NO_CONTENT_KEY_2; + case OEMCrypto_ERROR_INSUFFICIENT_RESOURCES: + return INSUFFICIENT_CRYPTO_RESOURCES_2; + case OEMCrypto_ERROR_UNKNOWN_FAILURE: + return UNKNOWN_SELECT_KEY_ERROR_1; + case OEMCrypto_ERROR_CONTROL_INVALID: + case OEMCrypto_ERROR_KEYBOX_INVALID: + default: + return UNKNOWN_SELECT_KEY_ERROR_2; } - - cached_key_id_ = key_id; - - const uint8_t* key_id_string = - reinterpret_cast(cached_key_id_.data()); - - OEMCryptoResult sts = - OEMCrypto_SelectKey(oec_session_id_, key_id_string, - cached_key_id_.size()); - if (OEMCrypto_SUCCESS != sts) { - cached_key_id_.clear(); - return false; - } - return true; } bool CryptoSession::GenerateDerivedKeys(const std::string& message) { - std::string mac_deriv_message; - std::string enc_deriv_message; - GenerateMacContext(message, &mac_deriv_message); - GenerateEncryptContext(message, &enc_deriv_message); - - LOGV("GenerateDerivedKeys: id=%ld", (uint32_t)oec_session_id_); - OEMCryptoResult sts = OEMCrypto_GenerateDerivedKeys( - oec_session_id_, - reinterpret_cast(mac_deriv_message.data()), - mac_deriv_message.size(), - reinterpret_cast(enc_deriv_message.data()), - enc_deriv_message.size()); - - if (OEMCrypto_SUCCESS != sts) { - LOGE("GenerateDerivedKeys: OEMCrypto_GenerateDerivedKeys error=%d", sts); - return false; - } - - return true; + return key_session_->GenerateDerivedKeys(message); } bool CryptoSession::GenerateDerivedKeys(const std::string& message, const std::string& session_key) { - std::string mac_deriv_message; - std::string enc_deriv_message; - GenerateMacContext(message, &mac_deriv_message); - GenerateEncryptContext(message, &enc_deriv_message); - - LOGV("GenerateDerivedKeys: id=%ld", (uint32_t)oec_session_id_); - OEMCryptoResult sts = OEMCrypto_DeriveKeysFromSessionKey( - oec_session_id_, reinterpret_cast(session_key.data()), - session_key.size(), - reinterpret_cast(mac_deriv_message.data()), - mac_deriv_message.size(), - reinterpret_cast(enc_deriv_message.data()), - enc_deriv_message.size()); - - if (OEMCrypto_SUCCESS != sts) { - LOGE("GenerateDerivedKeys: OEMCrypto_DeriveKeysFromSessionKey err=%d", sts); - return false; - } - - return true; + return key_session_->GenerateDerivedKeys(message, session_key); } bool CryptoSession::GenerateSignature(const std::string& message, @@ -801,7 +1187,7 @@ CdmResponseType CryptoSession::Decrypt(const CdmDecryptionParameters& params) { AutoLock auto_lock(crypto_lock_); // Check if key needs to be selected if (params.is_encrypted) { - if (!SelectKey(*params.key_id)) { + if (NO_ERROR != SelectKey(*params.key_id)) { return NEED_KEY; } } @@ -810,12 +1196,13 @@ CdmResponseType CryptoSession::Decrypt(const CdmDecryptionParameters& params) { params.is_encrypted, &(*params.iv).front(), params.block_offset, &buffer_descriptor, &pattern_descriptor, params.subsample_flags); + sts = key_session_->Decrypt(params, buffer_descriptor, pattern_descriptor); if (sts == OEMCrypto_ERROR_BUFFER_TOO_LARGE) { - // OEMCrypto_DecryptCENC rejected the buffer as too large, so chunk it up - // into sections no more than 100 KiB. The exact chunk size needs to be - // an even number of pattern repetitions long or else the pattern will get - // out of sync. + // OEMCrypto_DecryptCENC rejected the buffer as too large, so chunk it + // up into sections no more than 100 KiB. The exact chunk size needs to + // be an even number of pattern repetitions long or else the pattern + // will get out of sync. const size_t pattern_length = (pattern_descriptor.encrypt + pattern_descriptor.skip) * kAes128BlockSize; @@ -1015,8 +1402,10 @@ CdmResponseType CryptoSession::DeleteUsageInformation( reinterpret_cast(provider_session_token.c_str()), provider_session_token.length()); if (OEMCrypto_SUCCESS != status) { - LOGE("CryptoSession::DeleteUsageInformation: Delete Usage Table error =%ld", - status); + LOGE( + "CryptoSession::DeleteUsageInformation: Delete Usage Table error " + "=%ld", + status); response = UNKNOWN_ERROR; } status = OEMCrypto_UpdateUsageTable(); @@ -1239,7 +1628,9 @@ bool CryptoSession::GetHdcpCapabilities(HdcpCapability* current, LOGV("GetHdcpCapabilities: id=%ld", (uint32_t)oec_session_id_); if (!initialized_) return false; if (current == NULL || max == NULL) { - LOGE("CryptoSession::GetHdcpCapabilities: |current|, |max| cannot be NULL"); + LOGE( + "CryptoSession::GetHdcpCapabilities: |current|, |max| cannot be " + "NULL"); return false; } OEMCryptoResult status = OEMCrypto_GetHDCPCapability( @@ -1323,7 +1714,7 @@ CdmResponseType CryptoSession::GenericEncrypt(const std::string& in_buffer, } AutoLock auto_lock(crypto_lock_); - if (!SelectKey(key_id)) { + if (NO_ERROR != SelectKey(key_id)) { return KEY_ERROR_1; } @@ -1364,7 +1755,7 @@ CdmResponseType CryptoSession::GenericDecrypt(const std::string& in_buffer, } AutoLock auto_lock(crypto_lock_); - if (!SelectKey(key_id)) { + if (NO_ERROR != SelectKey(key_id)) { return KEY_ERROR_2; } @@ -1405,7 +1796,7 @@ CdmResponseType CryptoSession::GenericSign(const std::string& message, size_t length = signature->size(); AutoLock auto_lock(crypto_lock_); - if (!SelectKey(key_id)) { + if (NO_ERROR != SelectKey(key_id)) { return KEY_ERROR_3; } @@ -1452,7 +1843,7 @@ CdmResponseType CryptoSession::GenericVerify(const std::string& message, } AutoLock auto_lock(crypto_lock_); - if (!SelectKey(key_id)) { + if (NO_ERROR != SelectKey(key_id)) { return KEY_ERROR_4; } @@ -1473,6 +1864,65 @@ CdmResponseType CryptoSession::GenericVerify(const std::string& message, return NO_ERROR; } +CdmResponseType CryptoSession::AddSubSession( + const std::string& sub_session_key_id) { + size_t exists = sub_license_oec_sessions_.count(sub_session_key_id); + if (exists > 0) { + // TODO(jfore): Should this be an error if the key exists? If so add a new + // error. If not, perhaps this should just print info message. + LOGE("AddSubSession: SubSession already exists for id: %s", + sub_session_key_id.c_str()); + return UNKNOWN_ERROR; + } + + CryptoSessionId sid; + OEMCryptoResult sts = OEMCrypto_OpenSession(&sid, requested_security_level_); + if (OEMCrypto_ERROR_TOO_MANY_SESSIONS == sts) { + LOGE("OEMCrypto_Open failed: %d, open sessions: %ld, initialized: %d", + sts, session_count_, (int)initialized_); + return INSUFFICIENT_CRYPTO_RESOURCES; + } else if (OEMCrypto_SUCCESS != sts) { + LOGE("OEMCrypto_Open failed: %d, open sessions: %ld, initialized: %d", + sts, session_count_, (int)initialized_); + return UNKNOWN_ERROR; + } + + sts = OEMCrypto_LoadDeviceRSAKey( + sid, reinterpret_cast(wrapped_key_.data()), + wrapped_key_.size()); + + sub_license_oec_sessions_[sub_session_key_id] = sid; + if (key_session_->Type() != KeySession::kSubLicense) { + key_session_.reset(new SubLicenseKeySession( + sub_license_oec_sessions_, wrapped_key_, requested_security_level_)); + } + return NO_ERROR; +} + +bool CryptoSession::GenerateSubSessionNonce( + const std::string& sub_session_key_id, bool* exists, uint32_t* nonce) { + if (!exists || !nonce) { + LOGE("input parameter is null"); + return false; + } + + LOGV("CryptoSession::GenerateSubSessionNonce: Lock"); + AutoLock auto_lock(crypto_lock_); + + SubLicenseSessionMap::iterator it = + sub_license_oec_sessions_.find(sub_session_key_id); + if (it == sub_license_oec_sessions_.end()) { + // A subsession does not exist. Indicate that and return success. + *exists = false; + return true; + } + *exists = true; + + OEMCryptoResult result; + result = OEMCrypto_GenerateNonce(it->second, nonce); + return OEMCrypto_SUCCESS == result; +} + OEMCrypto_Algorithm CryptoSession::GenericSigningAlgorithm( CdmSigningAlgorithm algorithm) { if (kSigningAlgorithmHmacSha256 == algorithm) { @@ -1514,8 +1964,8 @@ OEMCryptoResult CryptoSession::CopyBufferInChunks( const size_t additional_offset = params.encrypt_length - remaining_encrypt_length; - // Update the remaining length of the original buffer only after calculating - // the new values. + // Update the remaining length of the original buffer only after + // calculating the new values. remaining_encrypt_length -= chunk_size; // Update the destination buffer with the new offset. @@ -1583,8 +2033,8 @@ OEMCryptoResult CryptoSession::DecryptInChunks( // calculating the new values. remaining_encrypt_length -= chunk_size; - // Update the destination buffer with the new offset. Because OEMCrypto can - // modify the OEMCrypto_DestBufferDesc during the call to + // Update the destination buffer with the new offset. Because OEMCrypto + // can modify the OEMCrypto_DestBufferDesc during the call to // OEMCrypto_DecryptCENC, (and is known to do so on some platforms) a new // OEMCrypto_DestBufferDesc must be allocated for each call. OEMCrypto_DestBufferDesc buffer_descriptor = full_buffer_descriptor; @@ -1655,8 +2105,8 @@ OEMCryptoResult CryptoSession::DecryptInChunks( // For cbcs, we must look for the last encrypted block, which is // probably not the last block of the subsample. Luckily, since the // buffer size is guaranteed to be an even number of pattern - // repetitions long, we can use the pattern to know how many blocks to - // look back. + // repetitions long, we can use the pattern to know how many blocks + // to look back. block_end = buffer_end - kAes128BlockSize * pattern_descriptor.skip; } diff --git a/core/src/initialization_data.cpp b/core/src/initialization_data.cpp index 5fa64d84..28f9f021 100644 --- a/core/src/initialization_data.cpp +++ b/core/src/initialization_data.cpp @@ -35,9 +35,9 @@ const int kDefaultNumJsonTokens = 128; namespace wvcdm { // Protobuf generated classes. -using video_widevine::WidevineCencHeader; -using video_widevine::WidevineCencHeader_Algorithm; -using video_widevine::WidevineCencHeader_Algorithm_AESCTR; +using video_widevine::WidevinePsshData; +using video_widevine::WidevinePsshData_Algorithm; +using video_widevine::WidevinePsshData_Algorithm_AESCTR; InitializationData::InitializationData(const std::string& type, const CdmInitData& data) @@ -70,6 +70,22 @@ InitializationData::InitializationData(const std::string& type, } } +// Parse the pssh data and return the embedded key data if it exists. +std::vector +InitializationData::ExtractEmbeddedKeys() const { + std::vector keys; + WidevinePsshData cenc_header; + if (!is_cenc_ || !cenc_header.ParseFromString(data_) || + cenc_header.sub_licenses().size() == 0) + return keys; + + keys.reserve(cenc_header.sub_licenses().size()); + for (int i = 0; i < cenc_header.sub_licenses().size(); ++i) { + keys.push_back(cenc_header.sub_licenses(i)); + } + return keys; +} + // Parse a blob of multiple concatenated PSSH atoms to extract the first // Widevine PSSH. bool InitializationData::ExtractWidevinePssh(const CdmInitData& init_data, @@ -339,8 +355,9 @@ bool InitializationData::ConstructWidevineInitData( return false; } if (method != kHlsMethodAes128 && method != kHlsMethodSampleAes) { - LOGV("InitializationData::ConstructWidevineInitData: Invalid method" - " parameter"); + LOGV( + "InitializationData::ConstructWidevineInitData: Invalid method" + " parameter"); return false; } @@ -466,10 +483,10 @@ bool InitializationData::ConstructWidevineInitData( } // Now format as Widevine init data protobuf - WidevineCencHeader cenc_header; + WidevinePsshData cenc_header; // TODO(rfrias): The algorithm is a deprecated field, but proto changes // have not yet been pushed to production. Set until then. - cenc_header.set_algorithm(WidevineCencHeader_Algorithm_AESCTR); + cenc_header.set_algorithm(WidevinePsshData_Algorithm_AESCTR); for (size_t i = 0; i < key_ids.size(); ++i) { cenc_header.add_key_id(key_ids[i]); } diff --git a/core/src/license.cpp b/core/src/license.cpp index 78762f99..1283d1e7 100644 --- a/core/src/license.cpp +++ b/core/src/license.cpp @@ -48,17 +48,41 @@ using video_widevine::ClientIdentification_NameValue; using video_widevine::DrmDeviceCertificate; using video_widevine::EncryptedClientIdentification; using video_widevine::License; -using video_widevine::License_KeyContainer; using video_widevine::LicenseError; using video_widevine::LicenseIdentification; using video_widevine::LicenseRequest; using video_widevine::LicenseRequest_ContentIdentification; using video_widevine::LicenseRequest_ContentIdentification_CencDeprecated; -using video_widevine::LicenseRequest_ContentIdentification_WebmDeprecated; using video_widevine::LicenseRequest_ContentIdentification_ExistingLicense; +using video_widevine::LicenseRequest_ContentIdentification_WebmDeprecated; +using video_widevine::License_KeyContainer; using video_widevine::SignedDrmDeviceCertificate; using video_widevine::SignedMessage; +static std::vector ExtractSubSessionKeys(const License& license) { + std::vector key_array; + + // Extract sub session key(s) + for (int i = 0; i < license.key_size(); ++i) { + CryptoKey key; + switch (license.key(i).type()) { + case License_KeyContainer::SUB_SESSION: + key.set_key_data(license.key(i).key()); + key.set_key_data_iv(license.key(i).iv()); + key.set_key_id(license.key(i).id()); + key.set_track_label(license.key(i).track_label()); + key_array.push_back(key); + break; + + default: + // Ignore all but SUB_SESSION key types. + break; + } + } + + return key_array; +} + static std::vector ExtractContentKeys(const License& license) { std::vector key_array; @@ -87,6 +111,7 @@ static std::vector ExtractContentKeys(const License& license) { if (license.has_protection_scheme()) { four_cc = license.protection_scheme(); } + key.set_track_label(license.key(i).track_label()); switch (four_cc) { // b/30713238: Android N assumed that the "protection scheme" Four // CC code, after being extracted from the protobuf, was host byte @@ -115,11 +140,28 @@ static std::vector ExtractContentKeys(const License& license) { } break; default: - // Ignore SIGNING key types as they are not content related + // Ignore SIGNING and SUB_SESSION key types as they are not content + // related. break; } } + std::vector sub_session_keys = ExtractSubSessionKeys(license); + // Match the track label from the key arrays and add sub_license_key_id to + // the content key array. + LOGI("Received %d subsession keys", sub_session_keys.size()); + if (!sub_session_keys.empty()) { + for (int i = 0; i < key_array.size(); ++i) { + if (key_array[i].track_label().empty()) continue; + for (int x = 0; x < sub_session_keys.size(); ++x) { + if (sub_session_keys[x].track_label() == key_array[i].track_label()) { + key_array[i].set_sub_session_key_id(sub_session_keys[x].key_id()); + key_array[i].set_sub_session_key(sub_session_keys[x].key_data()); + } + } + } + } + return key_array; } @@ -221,8 +263,8 @@ CdmResponseType CdmLicense::PrepareKeyRequest( status = PrepareClientId(app_parameters, &license_request); if (NO_ERROR != status) return status; - status = PrepareContentId(init_data, license_type, request_id, - &license_request); + status = + PrepareContentId(init_data, license_type, request_id, &license_request); if (NO_ERROR != status) return status; license_request.set_type(LicenseRequest::NEW); @@ -237,6 +279,37 @@ CdmResponseType CdmLicense::PrepareKeyRequest( } license_request.set_key_control_nonce(nonce); LOGD("PrepareKeyRequest: nonce=%u", nonce); + + // Prepare the request for any embedded keys that may exist in the + // initialization data. + std::vector embedded_key_data = + init_data.ExtractEmbeddedKeys(); + for (int i = 0; i < embedded_key_data.size(); ++i) { + bool exists = false; + if (!crypto_session_->GenerateSubSessionNonce( + embedded_key_data[i].sub_session_key_id(), &exists, &nonce)) { + return LICENSE_REQUEST_NONCE_GENERATION_ERROR; + } + if (exists) { + SignedMessage signed_sub_license; + License_KeyContainer keyc; + + // Parse the sub license for this track to extract the label. + if (!signed_sub_license.ParseFromString(embedded_key_data[i].key_msg()) || + !keyc.ParseFromString(signed_sub_license.msg()) || + keyc.track_label().empty()) { + return LICENSE_REQUEST_INVALID_SUBLICENSE; + } + + LicenseRequest::SubSessionData* sub_session_data = + license_request.add_sub_session_data(); + sub_session_data->set_sub_session_key_id( + embedded_key_data[i].sub_session_key_id()); + sub_session_data->set_nonce(nonce); + sub_session_data->set_track_label(keyc.track_label()); + } + } + license_request.set_protocol_version(video_widevine::VERSION_2_1); // License request is complete. Serialize it. @@ -438,7 +511,6 @@ CdmResponseType CdmLicense::HandleKeyResponse( LOGE("CdmLicense::HandleKeyResponse: no session keys present"); return SESSION_KEYS_NOT_FOUND; } - if (!crypto_session_->GenerateDerivedKeys(key_request_, signed_response.session_key())) return GENERATE_DERIVED_KEYS_ERROR; @@ -492,7 +564,8 @@ CdmResponseType CdmLicense::HandleKeyResponse( renew_with_client_id_ = license.policy().always_include_client_id(); } - CdmResponseType resp = crypto_session_->LoadKeys( + CdmResponseType resp = NO_ERROR; + resp = crypto_session_->LoadKeys( signed_response.msg(), signed_response.signature(), mac_key_iv, mac_key, key_array, provider_session_token_); @@ -587,6 +660,45 @@ CdmResponseType CdmLicense::HandleKeyUpdateResponse( } } +CdmResponseType CdmLicense::HandleSubLicense( + const InitializationData& init_data) { + std::vector subkeys = + init_data.ExtractEmbeddedKeys(); + std::set loaded_keys; + // Build a license with the rotated keys. + License license; + for (int i = 0; i < subkeys.size(); ++i) { + SignedMessage sm; + if (!sm.ParseFromString(subkeys[i].key_msg())) { + return LICENSE_REQUEST_INVALID_SUBLICENSE; + } + License_KeyContainer keyc; + if (!keyc.ParseFromString(sm.msg())) { + return LICENSE_REQUEST_INVALID_SUBLICENSE; + } + std::vector keys; + keys.resize(1); + keys[0].set_key_id(keyc.id()); + keys[0].set_key_data(keyc.key()); + keys[0].set_key_data_iv(keyc.iv()); + keys[0].set_key_control(keyc.key_control().key_control_block()); + keys[0].set_key_control_iv(keyc.key_control().iv()); + keys[0].set_track_label(keyc.track_label()); + CdmResponseType result = crypto_session_->LoadKeys( + sm.msg(), sm.signature(), std::string(), std::string(), keys, + std::string()); + if (result != KEY_ADDED) { + return result; + } + loaded_keys.insert(keyc.id()); + *license.add_key() = keyc; + } + loaded_keys_.swap(loaded_keys); + policy_engine_->UpdateLicenseKeys(license); + + return KEY_MESSAGE; +} + bool CdmLicense::RestoreOfflineLicense( const CdmKeyMessage& license_request, const CdmKeyResponse& license_response, @@ -994,8 +1106,7 @@ CdmResponseType CdmLicense::PrepareContentId( template bool CdmLicense::SetTypeAndId(CdmLicenseType license_type, - const std::string& request_id, - T* content_id) { + const std::string& request_id, T* content_id) { switch (license_type) { case kLicenseTypeOffline: content_id->set_license_type(video_widevine::OFFLINE); diff --git a/core/src/license_protocol.proto b/core/src/license_protocol.proto index bb76a90c..9d432c72 100644 --- a/core/src/license_protocol.proto +++ b/core/src/license_protocol.proto @@ -101,6 +101,7 @@ message License { CONTENT = 2; KEY_CONTROL = 3; OPERATOR_SESSION = 4; + SUB_SESSION = 5; } // The SecurityLevel enumeration allows the server to communicate the level @@ -199,6 +200,9 @@ message License { // supports anti rollback of the user table. Content provider can query the // client capabilities to determine if the client support this feature. optional bool anti_rollback_usage_table = 11 [default = false]; + // Optional not limited to commonly known track types such as SD, HD. + // It can be some provider defined label to identify the track. + optional string track_label = 12; } optional LicenseIdentification id = 1; @@ -266,6 +270,19 @@ message LicenseRequest { //} } + message SubSessionData { + // Required. The key ID for the corresponding SUB_SESSION_KEY. The + // value must match the sub_session_key_id field for a + // corresponding SubLicense message from the PSSH. + optional string sub_session_key_id = 1; + // Required. The nonce for the track. + optional uint32 nonce = 2; + // Required for initial license request used for each CONTENT key_container + // to know which nonce to use for building its key control block. + // Not needed for renewal license request. + optional string track_label = 3; + } + enum RequestType { NEW = 1; RENEWAL = 2; @@ -289,6 +306,9 @@ message LicenseRequest { optional uint32 key_control_nonce = 7; // Encrypted ClientIdentification message, used for privacy purposes. optional EncryptedClientIdentification encrypted_client_id = 8; + // Optional sub session context information. Required for using + // SubLicenses from the PSSH. + repeated SubSessionData sub_session_data = 9; } message LicenseError { @@ -302,6 +322,7 @@ message LicenseError { // or similar circumstances. SERVICE_UNAVAILABLE = 3; } + optional Error error_code = 1; } @@ -406,7 +427,7 @@ message ProvisioningOptions { optional CertificateType certificate_type = 1 [default = WIDEVINE_DRM]; // Contains the application-specific name used to identify the certificate - // authority for signing the generated certificate. This is required iff the + // authority for signing the generated certificate. This is required if the // certificate type is X509. optional string certificate_authority = 2; } @@ -665,19 +686,33 @@ message ProvisionedDeviceInfo { } // ---------------------------------------------------------------------------- -// widevine_header.proto +// widevine_pssh.proto // ---------------------------------------------------------------------------- // Description: // Public protocol buffer definitions for Widevine Cenc Header // protocol. -message WidevineCencHeader { +// Each SubLicense message represents a single content key. These keys can be +// added to Widevine CENC initialization data to support both content grouping +// and key rotation. +message SubLicense { + // Required. The key_id of a SUB_SESSION_KEY received in the master license. + // SUB_SESSION_KEY is defined in the Widevine License Protocol. + optional string sub_session_key_id = 1; + + // Required. The key_msg contains the bytes of a serialized SignedMessage + // proto. Internally the message field will contain a serialized KeyContainer + // holding a single content key. + optional bytes key_msg = 2; +} + +message WidevinePsshData { enum Algorithm { UNENCRYPTED = 0; AESCTR = 1; }; // Replaced with protection_scheme. - optional Algorithm algorithm = 1 [deprecated=true]; + optional Algorithm algorithm = 1; repeated bytes key_id = 2; // Content provider name. @@ -702,10 +737,22 @@ message WidevineCencHeader { // serialized SignedMessage. optional bytes grouped_license = 8; - // Protection scheme identifying the encryption algorithm. Represented as one - // of the following 4CC values: 'cenc' (AES-CTR), 'cbc1' (AES-CBC), - // 'cens' (AES-CTR subsample), 'cbcs' (AES-CBC subsample). + // Protection scheme identifying the encryption algorithm. The protection + // scheme is represented as a uint32 value. The uint32 contains 4 bytes each + // representing a single ascii character in one of the 4CC protection scheme + // values. + // 'cenc' (AES-CTR) protection_scheme = 0x63656E63, + // 'cbc1' (AES-CBC) protection_scheme = 0x63626331, + // 'cens' (AES-CTR subsample) protection_scheme = 0x63656E73, + // 'cbcs' (AES-CBC subsample) protection_scheme = 0x63626373. optional uint32 protection_scheme = 9; + + // Optional. For media using key rotation, this represents the duration + // of each crypto period in seconds. + optional uint32 crypto_period_seconds = 10; + + // Required when using content keys that are embedded in content. + repeated SubLicense sub_licenses = 11; } // Signed device certificate definition. diff --git a/core/src/oemcrypto_adapter_static_v12.cpp b/core/src/oemcrypto_adapter_static_v12.cpp index bdb7b36e..50f713cc 100644 --- a/core/src/oemcrypto_adapter_static_v12.cpp +++ b/core/src/oemcrypto_adapter_static_v12.cpp @@ -14,20 +14,17 @@ extern "C" OEMCrypto_ProvisioningMethod OEMCrypto_GetProvisioningMethod() { } extern "C" OEMCryptoResult OEMCrypto_GetOEMPublicCertificate( - OEMCrypto_SESSION session, uint8_t* public_cert, - size_t* public_cert_length) { + OEMCrypto_SESSION, uint8_t* /* public_cert */, + size_t* /* public_cert_length */) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; } extern "C" OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30( - OEMCrypto_SESSION session, - const uint32_t *nonce, - const uint8_t* encrypted_message_key, - size_t encrypted_message_key_length, - const uint8_t* enc_rsa_key, - size_t enc_rsa_key_length, - const uint8_t* enc_rsa_key_iv, - uint8_t* wrapped_rsa_key, - size_t* wrapped_rsa_key_length) { + OEMCrypto_SESSION, const uint32_t* /* nonce */, + const uint8_t* /* encrypted_message_key */, + size_t /* encrypted_message_key_length */, + const uint8_t* /* enc_rsa_key */, size_t /* enc_rsa_key_length */, + const uint8_t* /* enc_rsa_key_iv */, uint8_t* /* wrapped_rsa_key */, + size_t* /* wrapped_rsa_key_length */) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; } diff --git a/core/src/policy_engine.cpp b/core/src/policy_engine.cpp index 14d1a191..fb0ff28d 100644 --- a/core/src/policy_engine.cpp +++ b/core/src/policy_engine.cpp @@ -159,6 +159,14 @@ void PolicyEngine::SetLicense(const License& license) { UpdateLicense(license); } +void PolicyEngine::UpdateLicenseKeys(const video_widevine::License& license) { + // Use the current policy and set the new keys. + video_widevine::License loadable = license; + loadable.mutable_policy()->CopyFrom(policy_); + license_keys_->SetFromLicense(loadable); + NotifyKeysChange(kKeyStatusUsable); +} + void PolicyEngine::SetLicenseForRelease(const License& license) { license_id_.Clear(); license_id_.CopyFrom(license.id()); diff --git a/core/src/string_conversions.cpp b/core/src/string_conversions.cpp index 961ba603..7e7ecb76 100644 --- a/core/src/string_conversions.cpp +++ b/core/src/string_conversions.cpp @@ -10,14 +10,28 @@ #include #include -#include -#include - #include "log.h" namespace wvcdm { -static bool CharToDigit(char ch, unsigned char* digit) { +static const char kBase64Codes[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + +// Gets the low |n| bits of |in|. +#define GET_LOW_BITS(in, n) ((in) & ((1 << (n)) - 1)) +// Gets the given (zero-indexed) bits [a, b) of |in|. +#define GET_BITS(in, a, b) GET_LOW_BITS((in) >> (a), (b) - (a)) +// Calculates a/b using round-up division (only works for positive numbers). +#define CEIL_DIVIDE(a, b) ((((a) - 1) / (b)) + 1) + +int DecodeBase64Char(char c) { + const char* it = strchr(kBase64Codes, c); + if (it == NULL) + return -1; + return it - kBase64Codes; +} + +bool DecodeHexChar(char ch, unsigned char* digit) { if (ch >= '0' && ch <= '9') { *digit = ch - '0'; } else { @@ -43,8 +57,8 @@ std::vector a2b_hex(const std::string& byte) { for (unsigned int i = 0; i < count / 2; ++i) { unsigned char msb = 0; // most significant 4 bits unsigned char lsb = 0; // least significant 4 bits - if (!CharToDigit(byte[i * 2], &msb) || - !CharToDigit(byte[i * 2 + 1], &lsb)) { + if (!DecodeHexChar(byte[i * 2], &msb) || + !DecodeHexChar(byte[i * 2 + 1], &lsb)) { LOGE("Invalid hex value %c%c at index %d", byte[i * 2], byte[i * 2 + 1], i); return array; @@ -80,23 +94,50 @@ std::string b2a_hex(const std::string& byte) { } // Encode for standard base64 encoding (RFC4648). +// https://en.wikipedia.org/wiki/Base64 +// Text | M | a | n | +// ASCI | 77 (0x4d) | 97 (0x61) | 110 (0x6e) | +// Bits | 0 1 0 0 1 1 0 1 0 1 1 0 0 0 0 1 0 1 1 0 1 1 1 0 | +// Index | 19 | 22 | 5 | 46 | +// Base64 | T | W | F | u | +// | <----------------- 24-bits -----------------> | std::string Base64Encode(const std::vector& bin_input) { if (bin_input.empty()) { return std::string(); } - int in_size = bin_input.size(); - std::string b64_output(modp_b64_encode_len(in_size), 0); + // |temp| stores a 24-bit block that is treated as an array where insertions + // occur from high to low. + uint32_t temp = 0; + size_t out_index = 0; + const size_t out_size = CEIL_DIVIDE(bin_input.size(), 3) * 4; + std::string result(out_size, '\0'); + for (size_t i = 0; i < bin_input.size(); i++) { + // "insert" 8-bits of data + temp |= (bin_input[i] << ((2 - (i % 3)) * 8)); - int out_size = modp_b64_encode( - &b64_output[0], reinterpret_cast(&bin_input[0]), in_size); - if (out_size == -1) { - LOGE("Base64Encode failed"); - return std::string(); + if (i % 3 == 2) { + result[out_index++] = kBase64Codes[GET_BITS(temp, 18, 24)]; + result[out_index++] = kBase64Codes[GET_BITS(temp, 12, 18)]; + result[out_index++] = kBase64Codes[GET_BITS(temp, 6, 12)]; + result[out_index++] = kBase64Codes[GET_BITS(temp, 0, 6)]; + temp = 0; + } } - b64_output.resize(out_size); - return b64_output; + if (bin_input.size() % 3 == 1) { + result[out_index++] = kBase64Codes[GET_BITS(temp, 18, 24)]; + result[out_index++] = kBase64Codes[GET_BITS(temp, 12, 18)]; + result[out_index++] = '='; + result[out_index++] = '='; + } else if (bin_input.size() % 3 == 2) { + result[out_index++] = kBase64Codes[GET_BITS(temp, 18, 24)]; + result[out_index++] = kBase64Codes[GET_BITS(temp, 12, 18)]; + result[out_index++] = kBase64Codes[GET_BITS(temp, 6, 12)]; + result[out_index++] = '='; + } + + return result; } // Filename-friendly base64 encoding (RFC4648), commonly referred to @@ -111,18 +152,14 @@ std::string Base64SafeEncode(const std::vector& bin_input) { return std::string(); } - int in_size = bin_input.size(); - std::string b64_output(modp_b64w_encode_len(in_size), 0); - - int out_size = modp_b64w_encode( - &b64_output[0], reinterpret_cast(&bin_input[0]), in_size); - if (out_size == -1) { - LOGE("Base64SafeEncode failed"); - return std::string(); + std::string ret = Base64Encode(bin_input); + for (size_t i = 0; i < ret.size(); i++) { + if (ret[i] == '+') + ret[i] = '-'; + else if (ret[i] == '/') + ret[i] = '_'; } - - b64_output.resize(out_size); - return b64_output; + return ret; } std::string Base64SafeEncodeNoPad(const std::vector& bin_input) { @@ -138,17 +175,57 @@ std::vector Base64Decode(const std::string& b64_input) { return std::vector(); } - int in_size = b64_input.size(); - std::vector bin_output(modp_b64_decode_len(in_size), 0); - int out_size = modp_b64_decode(reinterpret_cast(&bin_output[0]), - b64_input.data(), in_size); - if (out_size == -1) { - LOGE("Base64Decode failed"); - return std::vector(0); + const size_t out_size_max = CEIL_DIVIDE(b64_input.size() * 3, 4); + std::vector result(out_size_max, '\0'); + + // |temp| stores 24-bits of data that is treated as an array where insertions + // occur from high to low. + uint32_t temp = 0; + size_t out_index = 0; + size_t i; + for (i = 0; i < b64_input.size(); i++) { + if (b64_input[i] == '=') { + // Verify an '=' only appears at the end. We want i to remain at the + // first '=', so we need an inner loop. + for (size_t j = i; j < b64_input.size(); j++) { + if (b64_input[j] != '=') { + LOGE("base64Decode failed"); + return std::vector(); + } + } + break; + } + + const int decoded = DecodeBase64Char(b64_input[i]); + if (decoded < 0) { + LOGE("base64Decode failed"); + return std::vector(); + } + // "insert" 6-bits of data + temp |= (decoded << ((3 - (i % 4)) * 6)); + + if (i % 4 == 3) { + result[out_index++] = GET_BITS(temp, 16, 24); + result[out_index++] = GET_BITS(temp, 8, 16); + result[out_index++] = GET_BITS(temp, 0, 8); + temp = 0; + } } - bin_output.resize(out_size); - return bin_output; + switch (i % 4) { + case 1: + LOGE("base64Decode failed"); + return std::vector(); + case 2: + result[out_index++] = GET_BITS(temp, 16, 24); + break; + case 3: + result[out_index++] = GET_BITS(temp, 16, 24); + result[out_index++] = GET_BITS(temp, 8, 16); + break; + } + result.resize(out_index); + return result; } // Decode for Filename-friendly base64 encoding (RFC4648), commonly referred @@ -158,22 +235,16 @@ std::vector Base64SafeDecode(const std::string& b64_input) { return std::vector(); } - std::string b64_padded(b64_input); - while (b64_padded.size() % 4 != 0) { - b64_padded = b64_padded + "="; + // Make a copy so we can modify it to replace the web-safe special characters + // with the normal ones. + std::string input_copy = b64_input; + for (size_t i = 0; i < input_copy.size(); i++) { + if (input_copy[i] == '-') + input_copy[i] = '+'; + else if (input_copy[i] == '_') + input_copy[i] = '/'; } - - int in_size = b64_padded.size(); - std::vector bin_output(modp_b64w_decode_len(in_size), 0); - int out_size = modp_b64w_decode(reinterpret_cast(&bin_output[0]), - b64_padded.data(), in_size); - if (out_size == -1) { - LOGE("Base64SafeDecode failed"); - return std::vector(0); - } - - bin_output.resize(out_size); - return bin_output; + return Base64Decode(input_copy); } std::string HexEncode(const uint8_t* in_buffer, unsigned int size) { diff --git a/core/test/base64_test.cpp b/core/test/base64_test.cpp index 44cefac4..1ac883ae 100644 --- a/core/test/base64_test.cpp +++ b/core/test/base64_test.cpp @@ -53,6 +53,9 @@ const std::pair kBase64TestVectors[] = make_pair(&kTwoBytesOverData, &kTwoBytesOverB64Data), make_pair(&kTestData, &kB64TestData)}; +const std::string kBase64ErrorVectors[] = {"Foo$sa", "Foo\x99\x23\xfa\02", + "Foo==Foo", "FooBa"}; + std::string ConvertToBase64WebSafe(const std::string &std_base64_string) { std::string str(std_base64_string); for (size_t i = 0; i < str.size(); ++i) { @@ -89,9 +92,19 @@ TEST_P(Base64EncodeDecodeTest, WebSafeEncodeDecodeTest) { EXPECT_STREQ(encoded_string.data(), b64_string.data()); } +class Base64ErrorDecodeTest : public ::testing::TestWithParam {}; + +TEST_P(Base64ErrorDecodeTest, EncoderErrors) { + std::vector result = Base64Decode(GetParam()); + EXPECT_EQ(0u, result.size()); +} + INSTANTIATE_TEST_CASE_P(ExecutesBase64Test, Base64EncodeDecodeTest, ::testing::ValuesIn(kBase64TestVectors)); +INSTANTIATE_TEST_CASE_P(ExecutesBase64Test, Base64ErrorDecodeTest, + ::testing::ValuesIn(kBase64ErrorVectors)); + class HtoNLL64Test : public ::testing::Test {}; TEST_F(HtoNLL64Test, PositiveNumber) { diff --git a/core/test/initialization_data_unittest.cpp b/core/test/initialization_data_unittest.cpp index d62e300b..c0c159b5 100644 --- a/core/test/initialization_data_unittest.cpp +++ b/core/test/initialization_data_unittest.cpp @@ -17,7 +17,7 @@ namespace wvcdm { // Protobuf generated classes. -using video_widevine::WidevineCencHeader; +using video_widevine::WidevinePsshData; namespace { @@ -164,6 +164,19 @@ const std::string kZeroSizedPsshBox = a2bs_hex( // data: "08011a0d7769646576696e655f74657374220f73747265616d696e675f636c697031"); +const std::string kSubLicensePsshBox = a2bs_hex( + // Widevine PSSH box + "0000009f" // atom size (whole buffer) + "70737368" // atom type="pssh" + "00000000" // v0, flags=0 + "edef8ba979d64acea3c827dcd51d21ed" // system id (Widevine) + "0000007f" // data size + // data: + "0801120d746573745f6b65795f69645f30120d746573745f6b65795f69645f31220f" + "746573745f636f6e74656e745f69645a250a147375625f73657373696f6e5f6b6579" + "5f69645f30120d7375625f6c6963656e73655f305a250a147375625f73657373696f" + "6e5f6b65795f69645f31120d7375625f6c6963656e73655f31"); + // HLS test attribute key and values const std::string kHlsIvHexValue = "6DF49213A781E338628D0E9C812D328E"; const std::string kHlsIvValue = "0x" + kHlsIvHexValue; @@ -353,7 +366,9 @@ struct HlsInitDataVariant { HlsInitDataVariant(CdmHlsMethod method, const std::string& provider, const std::string& content_id, const std::string& key_id, bool success) - : method_(method), provider_(provider), content_id_(content_id), + : method_(method), + provider_(provider), + content_id_(content_id), success_(success) { if (key_id.size() > 0) key_ids_.push_back(key_id); } @@ -410,13 +425,31 @@ TEST_P(InitializationDataTest, Parse) { EXPECT_FALSE(init_data.IsEmpty()); } -INSTANTIATE_TEST_CASE_P(ParsePssh, InitializationDataTest, - ::testing::Values(kWidevinePssh, kWidevinePsshFirst, - kWidevinePsshAfterV0Pssh, - kWidevinePsshAfterNonZeroFlags, - kWidevinePsshAfterV1Pssh, - kWidevineV1Pssh, kOtherBoxFirst, - kZeroSizedPsshBox)); +INSTANTIATE_TEST_CASE_P( + ParsePssh, InitializationDataTest, + ::testing::Values(kWidevinePssh, kWidevinePsshFirst, + kWidevinePsshAfterV0Pssh, kWidevinePsshAfterNonZeroFlags, + kWidevinePsshAfterV1Pssh, kWidevineV1Pssh, kOtherBoxFirst, + kZeroSizedPsshBox, kSubLicensePsshBox)); +TEST_F(InitializationDataTest, ExtractSubLicense) { + InitializationData init_data(ISO_BMFF_VIDEO_MIME_TYPE, kSubLicensePsshBox); + EXPECT_FALSE(init_data.IsEmpty()); + std::vector keys = + init_data.ExtractEmbeddedKeys(); + ASSERT_EQ(keys.size(), 2UL); + ASSERT_EQ(keys[0].sub_session_key_id(), "sub_session_key_id_0"); + ASSERT_EQ(keys[1].sub_session_key_id(), "sub_session_key_id_1"); + ASSERT_EQ(keys[0].key_msg(), "sub_license_0"); + ASSERT_EQ(keys[1].key_msg(), "sub_license_1"); +} + +TEST_F(InitializationDataTest, ExtractEmptySubLicense) { + InitializationData init_data(ISO_BMFF_VIDEO_MIME_TYPE, kWidevinePssh); + EXPECT_FALSE(init_data.IsEmpty()); + std::vector keys = + init_data.ExtractEmbeddedKeys(); + ASSERT_TRUE(keys.empty()); +} TEST_P(HlsKeyFormatVersionsExtractionTest, ExtractKeyFormatVersions) { std::vector versions = GetParam(); @@ -598,9 +631,9 @@ TEST_P(HlsConstructionTest, InitData) { EXPECT_EQ(param.success_, InitializationData::ConstructWidevineInitData( param.method_, uri, &value)); if (param.success_) { - WidevineCencHeader cenc_header; + WidevinePsshData cenc_header; EXPECT_TRUE(cenc_header.ParseFromString(value)); - EXPECT_EQ(video_widevine::WidevineCencHeader_Algorithm_AESCTR, + EXPECT_EQ(video_widevine::WidevinePsshData_Algorithm_AESCTR, cenc_header.algorithm()); for (size_t i = 0; i < param.key_ids_.size(); ++i) { bool key_id_found = false; @@ -620,9 +653,14 @@ TEST_P(HlsConstructionTest, InitData) { cenc_header.content_id()); uint32_t protection_scheme = 0; switch (param.method_) { - case kHlsMethodAes128: protection_scheme = kFourCcCbc1; break; - case kHlsMethodSampleAes: protection_scheme = kFourCcCbcs; break; - default: break; + case kHlsMethodAes128: + protection_scheme = kFourCcCbc1; + break; + case kHlsMethodSampleAes: + protection_scheme = kFourCcCbcs; + break; + default: + break; } EXPECT_EQ(protection_scheme, cenc_header.protection_scheme()); } @@ -633,8 +671,8 @@ INSTANTIATE_TEST_CASE_P( ::testing::Values( HlsInitDataVariant(kHlsMethodAes128, "", kHlsTestContentId, kHlsTestKeyId1, false), - HlsInitDataVariant(kHlsMethodAes128, kHlsTestProvider, - "", kHlsTestKeyId1, false), + HlsInitDataVariant(kHlsMethodAes128, kHlsTestProvider, "", + kHlsTestKeyId1, false), HlsInitDataVariant(kHlsMethodAes128, kHlsTestProvider, kHlsTestContentId, "", false), HlsInitDataVariant(kHlsMethodAes128, kHlsTestProvider, @@ -699,9 +737,9 @@ TEST_P(HlsParseTest, Parse) { EXPECT_EQ(kHlsMethodSampleAes, init_data.hls_method()); } - WidevineCencHeader cenc_header; + WidevinePsshData cenc_header; EXPECT_TRUE(cenc_header.ParseFromString(init_data.data())); - EXPECT_EQ(video_widevine::WidevineCencHeader_Algorithm_AESCTR, + EXPECT_EQ(video_widevine::WidevinePsshData_Algorithm_AESCTR, cenc_header.algorithm()); if (param.key_.compare(kJsonProvider) == 0) { EXPECT_EQ(param.value_, cenc_header.provider()); diff --git a/core/test/license_unittest.cpp b/core/test/license_unittest.cpp index 23ccd511..41fdd95e 100644 --- a/core/test/license_unittest.cpp +++ b/core/test/license_unittest.cpp @@ -79,6 +79,32 @@ const std::string kLicenseRequestSignature = a2bs_hex( "9AE18B91516E0CDD0B581590DDDEA2A2527E2C9ABA273629B586A9D22D451A827E332CFC3E" "9BEDB6CF3D8713F9E11675DF1F5DB9038DBBECAB9D1683F8722CAF6E18EC8C04AEE5"); +const std::string kSubLicensePssh = a2bs_hex( + "000002317073736800000000edef8ba979d64acea3c827dcd51d21ed000002010801120d54" + "6573744b6579415544494f30120a546573744b6579534430120a546573744b65794844301a" + "0048e3dc959b0650025a9b010a101f10e4700b1a5b731c545fe2405cea1b12860112620a0d" + "546573744b6579415544494f3012102f4b661d1064b5ea82efcd3ef850f45b1a10a02c5cea" + "5182383c064c06abbc79bfa8200242240a1023acc9a0ef2bca66af2a1307cc9edeb21210e1" + "f1d352b4c6b1aad1fd78423db256946205415544494f1a20aaf4537f09332c502a88f43a18" + "a3e21ec28bbde675c5d87054fbca06f98e98015a95010a10c034cf6ae181b8d07f2e79142d" + "792bb3128001125c0a0a546573744b657953443012106d37a0a201afdef8a494f89a4b0772" + "4a1a10457db86b73bf87177a5cc61c0d04b690200242240a1001fe432d2a8afb7054ae76a3" + "9c2727e612108761b7e0ba354ee4132117a9de12abd3620253441a20e3f37529cb795b35a0" + "d186e4ce7187f08dda5f1df136ddb92eb0a65a899635005a95010a1021cdec9b2105c6b643" + "e71f68e5302c85128001125c0a0a546573744b6579484430121012a3e3afe1e23be2c3fc55" + "fddad877451a108f31ff0865f4d4fb41d96414297f7728200242240a1061e3cbca755b36c8" + "e7d6dda03af20e4f1210a2fa2fc5d10c9c84ddc5511446ce77e9620248441a20a945699aef" + "49355b0214b636edb7670bbe350c58b69cd52f207953b380a52df2"); + +const std::string kSubSessionKeyID1 = + a2bs_hex("1f10e4700b1a5b731c545fe2405cea1b"); + +const std::string kSubSessionKeyID2 = + a2bs_hex("c034cf6ae181b8d07f2e79142d792bb3"); + +const std::string kSubSessionKeyID3 = + a2bs_hex("21cdec9b2105c6b643e71f68e5302c85"); + class MockCryptoSession : public CryptoSession { public: MOCK_METHOD0(IsOpen, bool()); @@ -88,6 +114,9 @@ class MockCryptoSession : public CryptoSession { MOCK_METHOD1(GetApiVersion, bool(uint32_t*)); MOCK_METHOD1(GenerateNonce, bool(uint32_t*)); MOCK_METHOD3(PrepareRequest, bool(const std::string&, bool, std::string*)); + MOCK_METHOD3(GenerateSubSessionNonce, + bool(const std::string& sub_session_key_id, bool* exists, + uint32_t* nonce)); }; class MockPolicyEngine : public PolicyEngine { @@ -126,11 +155,12 @@ using ::testing::SetArgPointee; class CdmLicenseTest : public ::testing::Test { protected: + CdmLicenseTest(const std::string& pssh = (kCencInitDataHdr + kCencPssh)) + : pssh_(pssh) {} virtual void SetUp() { clock_ = new MockClock(); - crypto_session_ = new MockCryptoSession(); - init_data_ = new MockInitializationData(CENC_INIT_DATA_FORMAT, - kCencInitDataHdr + kCencPssh); + crypto_session_ = new testing::StrictMock(); + init_data_ = new MockInitializationData(CENC_INIT_DATA_FORMAT, pssh_); policy_engine_ = new MockPolicyEngine(crypto_session_); } @@ -142,7 +172,7 @@ class CdmLicenseTest : public ::testing::Test { if (clock_) delete clock_; } - void CreateCdmLicense() { + virtual void CreateCdmLicense() { cdm_license_ = new CdmLicense(kCdmSessionId, clock_); clock_ = NULL; } @@ -153,6 +183,12 @@ class CdmLicenseTest : public ::testing::Test { MockInitializationData* init_data_; MockPolicyEngine* policy_engine_; ServiceCertificate service_cert_; + std::string pssh_; +}; + +class SubLicenseTest : public CdmLicenseTest { + protected: + SubLicenseTest() : CdmLicenseTest(kSubLicensePssh) {} }; TEST_F(CdmLicenseTest, InitSuccess) { @@ -303,4 +339,88 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidation) { EXPECT_EQ(kNonce, license_request.key_control_nonce()); } +TEST_F(SubLicenseTest, VerifySubSessionData) { + bool usage_information_support = true; + CryptoSession::HdcpCapability current_hdcp_version = HDCP_NO_DIGITAL_OUTPUT; + CryptoSession::HdcpCapability max_hdcp_version = HDCP_V2_1; + uint32_t crypto_session_api_version = 9; + + EXPECT_CALL(*crypto_session_, IsOpen()).WillOnce(Return(true)); + EXPECT_CALL(*crypto_session_, GenerateRequestId(NotNull())) + .WillOnce(DoAll(SetArgPointee<0>(kCryptoRequestId), Return(true))); + EXPECT_CALL(*crypto_session_, UsageInformationSupport(NotNull())) + .WillOnce( + DoAll(SetArgPointee<0>(usage_information_support), Return(true))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillOnce(DoAll(SetArgPointee<0>(current_hdcp_version), + SetArgPointee<1>(max_hdcp_version), Return(true))); + EXPECT_CALL(*crypto_session_, GetApiVersion(NotNull())) + .WillOnce( + DoAll(SetArgPointee<0>(crypto_session_api_version), Return(true))); + EXPECT_CALL(*clock_, GetCurrentTime()).WillOnce(Return(kLicenseStartTime)); + EXPECT_CALL(*crypto_session_, GenerateNonce(NotNull())) + .WillOnce(DoAll(SetArgPointee<0>(kNonce), Return(true))); + EXPECT_CALL(*crypto_session_, PrepareRequest(_, Eq(false), NotNull())) + .WillOnce( + DoAll(SetArgPointee<2>(kLicenseRequestSignature), Return(true))); + + // SubLicense session data calls. + // TODO(jfore): These calls are being invoked twice each. This should not + // present a functional problem, but we should investigate why. + EXPECT_CALL(*crypto_session_, + GenerateSubSessionNonce(kSubSessionKeyID1, NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<1>(true), SetArgPointee<2>(0), Return(true))); + EXPECT_CALL(*crypto_session_, + GenerateSubSessionNonce(kSubSessionKeyID2, NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<1>(true), SetArgPointee<2>(1), Return(true))); + EXPECT_CALL(*crypto_session_, + GenerateSubSessionNonce(kSubSessionKeyID3, NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<1>(true), SetArgPointee<2>(2), Return(true))); + + CreateCdmLicense(); + // TODO(gmorgan) fix below - no default service certificate + //service_cert_.Init(kDefaultServiceCertificate); + EXPECT_TRUE(cdm_license_->Init( + &service_cert_, kToken, kClientTokenDrmCert, kEmptyString, + crypto_session_, policy_engine_)); + CdmAppParameterMap app_parameters; + CdmKeyMessage signed_request; + Properties::set_use_certificates_as_identification(true); + std::string server_url; + EXPECT_EQ(cdm_license_->PrepareKeyRequest(*init_data_, kLicenseTypeStreaming, + app_parameters, &signed_request, + &server_url), + KEY_MESSAGE); + EXPECT_TRUE(!signed_request.empty()); + + SignedMessage signed_message; + EXPECT_TRUE(signed_message.ParseFromString(signed_request)); + LicenseRequest license_request; + EXPECT_TRUE(license_request.ParseFromString(signed_message.msg())); + EXPECT_EQ(3, license_request.sub_session_data().size()); + + for (int i = 0; i < license_request.sub_session_data().size(); ++i) { + const video_widevine::LicenseRequest_SubSessionData& sl = + license_request.sub_session_data(i); + EXPECT_EQ(static_cast(i), sl.nonce()); + switch (i) { + case 0: + EXPECT_EQ(kSubSessionKeyID1, sl.sub_session_key_id()); + EXPECT_EQ("AUDIO", sl.track_label()); + break; + case 1: + EXPECT_EQ(kSubSessionKeyID2, sl.sub_session_key_id()); + EXPECT_EQ("SD", sl.track_label()); + break; + case 3: + EXPECT_EQ(kSubSessionKeyID3, sl.sub_session_key_id()); + EXPECT_EQ("HD", sl.track_label()); + break; + } + } +} + } // namespace wvcdm diff --git a/core/test/test_printers.cpp b/core/test/test_printers.cpp index 8e7e7c25..72ceb8a1 100644 --- a/core/test/test_printers.cpp +++ b/core/test/test_printers.cpp @@ -487,6 +487,27 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) { break; case PARSE_RESPONSE_ERROR_4: *os << "PARSE_RESPONSE_ERROR_4"; break; + case LICENSE_REQUEST_INVALID_SUBLICENSE: + *os << "LICENSE_REQUEST_INVALID_SUBLICENSE"; + break; + case INVALID_SESSION_1: + *os << "INVALID_SESSION_1"; + break; + case NO_DEVICE_KEY_1: + *os << "NO_DEVICE_KEY_1"; + break; + case NO_CONTENT_KEY_2: + *os << "NO_CONTENT_KEY_2"; + break; + case INSUFFICIENT_CRYPTO_RESOURCES_2: + *os << "INSUFFICIENT_CRYPTO_RESOURCES_2"; + break; + case UNKNOWN_SELECT_KEY_ERROR_1: + *os << "UNKNOWN_SELECT_KEY_ERROR_1"; + break; + case UNKNOWN_SELECT_KEY_ERROR_2: + *os << "UNKNOWN_SELECT_KEY_ERROR_2"; + break; default: *os << "Unknown CdmResponseType"; break; diff --git a/oemcrypto/include/OEMCryptoCENC.h b/oemcrypto/include/OEMCryptoCENC.h index 6c224320..0e663be9 100644 --- a/oemcrypto/include/OEMCryptoCENC.h +++ b/oemcrypto/include/OEMCryptoCENC.h @@ -1626,7 +1626,7 @@ OEMCryptoResult OEMCrypto_GetRandom(uint8_t* randomData, size_t dataLength); * * Parameters: * session (in) - crypto session identifier. - * nonce (in) - The nonce provided in the provisioning response. + * unaligned_nonce (in) - The nonce provided in the provisioning response. * encrypted_message_key (in) - message_key encrypted by private key * - from OEM cert. * encrypted_message_key_length (in) - length of encrypted_message_key in @@ -1669,7 +1669,7 @@ OEMCryptoResult OEMCrypto_GetRandom(uint8_t* randomData, size_t dataLength); * This method is new in API version 12. */ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30( - OEMCrypto_SESSION session, const uint32_t* nonce, + OEMCrypto_SESSION session, const uint32_t* unaligned_nonce, const uint8_t* encrypted_message_key, size_t encrypted_message_key_length, const uint8_t* enc_rsa_key, size_t enc_rsa_key_length, const uint8_t* enc_rsa_key_iv, uint8_t* wrapped_rsa_key, @@ -1759,7 +1759,7 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30( * - signature for message, received from the * - provisioning server. * signature_length (in) - length of the signature, in bytes. - * nonce (in) - The nonce provided in the provisioning response. + * unaligned_nonce (in) - The nonce provided in the provisioning response. * enc_rsa_key (in) - Encrypted device private RSA key received from * - the provisioning server. Format is PKCS#8 * - binary DER encoded, encrypted with the derived @@ -1800,10 +1800,10 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30( OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey( OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, - const uint8_t* signature, size_t signature_length, const uint32_t* nonce, - const uint8_t* enc_rsa_key, size_t enc_rsa_key_length, - const uint8_t* enc_rsa_key_iv, uint8_t* wrapped_rsa_key, - size_t* wrapped_rsa_key_length); + const uint8_t* signature, size_t signature_length, + const uint32_t* unaligned_nonce, const uint8_t* enc_rsa_key, + size_t enc_rsa_key_length, const uint8_t* enc_rsa_key_iv, + uint8_t* wrapped_rsa_key, size_t* wrapped_rsa_key_length); /* * OEMCrypto_LoadDeviceRSAKey diff --git a/oemcrypto/test/oec_session_util.h b/oemcrypto/test/oec_session_util.h index 3f255c0c..ee8d661c 100644 --- a/oemcrypto/test/oec_session_util.h +++ b/oemcrypto/test/oec_session_util.h @@ -282,6 +282,7 @@ class Session { // The current number of keys to use in the license(), encrypted_license() // and key_array(). int num_keys() const { return num_keys_; } + size_t key_array_size() const { return num_keys_; } // Set the size of the buffer used the encrypted license. // Must be between sizeof(MessageData) and kMaxMessageSize. diff --git a/oemcrypto/test/oemcrypto_test.cpp b/oemcrypto/test/oemcrypto_test.cpp index 06f71b34..6728d9bd 100644 --- a/oemcrypto/test/oemcrypto_test.cpp +++ b/oemcrypto/test/oemcrypto_test.cpp @@ -937,7 +937,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange1) { s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, &mac_keys[0], // Not pointing into buffer. - s.num_keys(), s.key_array(), NULL, 0); + s.key_array_size(), s.key_array(), NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -955,7 +955,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange2) { s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), &mac_key_iv[0], // bad. - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.key_array_size(), s.key_array(), + NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -973,7 +974,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange3) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.key_array_size(), s.key_array(), + NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -992,7 +994,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange4) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.key_array_size(), s.key_array(), + NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1009,7 +1012,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange5) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.key_array_size(), s.key_array(), + NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1028,7 +1032,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange6) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.key_array_size(), s.key_array(), + NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1047,7 +1052,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange7) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.key_array_size(), s.key_array(), + NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1062,7 +1068,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadNonce) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.key_array_size(), s.key_array(), + NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1087,7 +1094,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithRepeatNonce) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.key_array_size(), s.key_array(), + NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1102,7 +1110,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadVerification) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.key_array_size(), s.key_array(), + NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1136,7 +1145,8 @@ TEST_P(SessionTestAlternateVerification, LoadKeys) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.key_array_size(), s.key_array(), + NULL, 0); // If this is a future API, then LoadKeys should fail. if (global_features.api_version < target_api_) { ASSERT_NE(OEMCrypto_SUCCESS, sts); @@ -1162,7 +1172,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeysBadSignature) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.key_array_size(), s.key_array(), + NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1175,7 +1186,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeysWithNoDerivedKeys) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.key_array_size(), s.key_array(), + NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1247,7 +1259,8 @@ TEST_F(OEMCryptoSessionTests, AntiRollbackHardwareRequired) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.key_array_size(), s.key_array(), + NULL, 0); if (OEMCrypto_IsAntiRollbackHwPresent()) { ASSERT_EQ(OEMCrypto_SUCCESS, sts); } else { @@ -1270,7 +1283,7 @@ TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) { OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), + s.encrypted_license().mac_keys, s.key_array_size(), s.key_array(), NULL, 0)); } if (patch_level < 0x3F) { @@ -1286,7 +1299,7 @@ TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) { OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), + s.encrypted_license().mac_keys, s.key_array_size(), s.key_array(), NULL, 0)); } if (patch_level > 0) { @@ -1302,7 +1315,7 @@ TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) { OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), + s.encrypted_license().mac_keys, s.key_array_size(), s.key_array(), NULL, 0)); } } @@ -4457,7 +4470,7 @@ TEST_F(UsageTableTest, RepeatOnlineLicense) { OEMCrypto_LoadKeys(s2.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), + s.encrypted_license().mac_keys, s.key_array_size(), s.key_array(), pst_ptr, pst.length())); ASSERT_NO_FATAL_FAILURE(s2.close()); } @@ -4475,7 +4488,8 @@ TEST_F(UsageTableTest, OnlineEmptyPST) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.key_array_size(), s.key_array(), + NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); ASSERT_NO_FATAL_FAILURE(s.close()); } @@ -5160,7 +5174,7 @@ TEST_P(UsageTableTestWithMAC, BadReloadOfflineLicense) { OEMCrypto_LoadKeys(s2.session_id(), s2.message_ptr(), s2.message_size(), &s2.signature()[0], s2.signature().size(), s2.encrypted_license().mac_key_iv, - s2.encrypted_license().mac_keys, s.num_keys(), + s2.encrypted_license().mac_keys, s.key_array_size(), s2.key_array(), pst_ptr, pst.length())); ASSERT_NO_FATAL_FAILURE(s2.close()); @@ -5186,8 +5200,8 @@ TEST_P(UsageTableTestWithMAC, OfflineBadNonce) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), pst_ptr, - pst.length()); + s.encrypted_license().mac_keys, s.key_array_size(), s.key_array(), + pst_ptr, pst.length()); ASSERT_NE(OEMCrypto_SUCCESS, sts); ASSERT_NO_FATAL_FAILURE(s.close()); } @@ -5204,7 +5218,8 @@ TEST_P(UsageTableTestWithMAC, OfflineEmptyPST) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.key_array_size(), s.key_array(), + NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); ASSERT_NO_FATAL_FAILURE(s.close()); } @@ -5241,7 +5256,7 @@ TEST_P(UsageTableTestWithMAC, DeactivateOfflineLicense) { OEMCrypto_LoadKeys(s2.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), + s.encrypted_license().mac_keys, s.key_array_size(), s.key_array(), pst_ptr, pst.length())); // But we can still generate a report. Session s3; @@ -5265,7 +5280,7 @@ TEST_P(UsageTableTestWithMAC, BadRange) { OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), + s.encrypted_license().mac_keys, s.key_array_size(), s.key_array(), pst_ptr, pst.length())); } @@ -5531,7 +5546,7 @@ TEST_F(UsageTableTest, PSTLargeBuffer) { OEMCrypto_LoadKeys(s2.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), + s.encrypted_license().mac_keys, s.key_array_size(), s.key_array(), pst_ptr, pst.length())); // But we can still generate a report. Session s3; diff --git a/platforms/x86-64/settings.gypi b/platforms/x86-64/settings.gypi index ceb39b2c..aab510ca 100644 --- a/platforms/x86-64/settings.gypi +++ b/platforms/x86-64/settings.gypi @@ -11,19 +11,41 @@ 'target_defaults': { # These are flags passed to the compiler for all C & C++ files. 'cflags': [ - '-fPIC', - '-fno-exceptions', - # Enable all warnings, and treat warnings as errors. - '-Wall', - '-Werror', ], # These are flags passed to the compiler for plain C only. 'cflags_c': [ + '-Wbad-function-cast', ], # These are flags passed to the compiler for C++ only. 'cflags_cc': [ + '-fPIC', + '-fno-rtti', + '-fno-exceptions', + # Enable all warnings, and treat warnings as errors. + '-Wall', + '-Werror', + '-Wextra', + '-Wunused', + '-fno-rtti', + '-Wcast-qual', + '-Wno-long-long', + '-Wno-variadic-macros', + '-Wno-inline', + '-Wformat=2', + '-Wno-format-nonliteral', + '-Wshadow', + '-Wnon-virtual-dtor', + '-Woverloaded-virtual', + '-Wctor-dtor-privacy', + '-Wcast-align', + '-Wno-conversion', + '-Wignored-qualifiers', + '-Wreturn-type', + #'-Wstrict-null-sentinel', + #'-Wuseless-cast', + '-Wno-unused-parameter', # repeated in protobufs triggers this ], # These are flags passed to the linker. @@ -53,6 +75,26 @@ ], 'cflags_cc=': [ + #'-fno-rtti', + '-Wcast-qual', + '-Wextra', + '-Wunused', + '-Wno-long-long', + '-Wno-variadic-macros', + '-Wno-inline', + '-Wformat=2', + '-Wno-format-nonliteral', + #'-Wshadow', + '-Wnon-virtual-dtor', + '-Woverloaded-virtual', + #'-Wstrict-null-sentinel', + '-Wctor-dtor-privacy', + #'-Wbad-function-cast', + '-Wcast-align', + #'-Wconversion', + #'-Wuseless-cast', + '-Wno-ignored-qualifiers', + '-Wno-return-type', ], 'ldflags=': [ @@ -78,6 +120,7 @@ }, { # disable_cpp_11 != 1 'cflags_cc': [ '-std=c++11', + '-Wc++11-compat', ], }], # end disable_cpp_11 == 1 condition ], # end target_conditions diff --git a/third_party/gmock.gyp b/third_party/gmock.gyp index 64119ce9..b7c54b02 100644 --- a/third_party/gmock.gyp +++ b/third_party/gmock.gyp @@ -15,6 +15,22 @@ 'googletest/googletest/include', ], }, + # These flags silence warnings that appear in gtest/gmock upstream. + # We will not maintain a divergent copy of gmock to fix them. + 'cflags': [ + # Ignore unknown warning options, to support both gcc & clang at once. + '-Wno-unknown-warning-option', + ], + 'cflags_cc': [ + '-Wno-sign-compare', + #'-Wno-unused-const-variable', + #'-Wno-unused-function', + #'-Wno-unused-parameter', + #'-Wno-shadow', + '-Wno-conversion', + '-Wno-sign-conversion', + #'-Wno-useless-cast', + ], }, 'targets': [ { diff --git a/third_party/gyp/common.py b/third_party/gyp/common.py index a1e1db5f..0f01ec64 100644 --- a/third_party/gyp/common.py +++ b/third_party/gyp/common.py @@ -429,6 +429,8 @@ def GetFlavor(params): return 'netbsd' if sys.platform.startswith('aix'): return 'aix' + if sys.platform.startswith('os390'): + return 'os390' return 'linux' diff --git a/third_party/gyp/easy_xml.py b/third_party/gyp/easy_xml.py index bf949b6a..2522efb2 100644 --- a/third_party/gyp/easy_xml.py +++ b/third_party/gyp/easy_xml.py @@ -4,6 +4,7 @@ import re import os +import locale def XmlToString(content, encoding='utf-8', pretty=False): @@ -116,6 +117,10 @@ def WriteXmlIfChanged(content, path, encoding='utf-8', pretty=False, if win32 and os.linesep != '\r\n': xml_string = xml_string.replace('\n', '\r\n') + default_encoding = locale.getdefaultlocale()[1] + if default_encoding and default_encoding.upper() != encoding.upper(): + xml_string = xml_string.decode(default_encoding).encode(encoding) + # Get the old content try: f = open(path, 'r') diff --git a/third_party/gyp/generator/make.py b/third_party/gyp/generator/make.py index e80ebaed..e8890474 100644 --- a/third_party/gyp/generator/make.py +++ b/third_party/gyp/generator/make.py @@ -232,6 +232,24 @@ cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSE """ +LINK_COMMANDS_OS390 = """\ +quiet_cmd_alink = AR($(TOOLSET)) $@ +cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^) + +quiet_cmd_alink_thin = AR($(TOOLSET)) $@ +cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) crsT $@ $(filter %.o,$^) + +quiet_cmd_link = LINK($(TOOLSET)) $@ +cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(LD_INPUTS) + +quiet_cmd_solink = SOLINK($(TOOLSET)) $@ +cmd_solink = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(LD_INPUTS) $(LIBS) -Wl,DLL + +quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ +cmd_solink_module = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS) -Wl,DLL +""" + + # Header of toplevel Makefile. # This should go into the build tree, but it's easier to keep it here for now. SHARED_HEADER = ("""\ @@ -315,7 +333,7 @@ dirx = $(call unreplace_spaces,$(dir $(call replace_spaces,$1))) # We write to a dep file on the side first and then rename at the end # so we can't end up with a broken dep file. depfile = $(depsdir)/$(call replace_spaces,$@).d -DEPFLAGS = -MMD -MF $(depfile).raw +DEPFLAGS = %(makedep_args)s -MF $(depfile).raw # We have to fixup the deps output in a few ways. # (1) the file output should mention the proper .o file. @@ -2022,6 +2040,7 @@ def GenerateOutput(target_list, target_dicts, data, params): flock_command= 'flock' copy_archive_arguments = '-af' + makedep_arguments = '-MMD' header_params = { 'default_target': default_target, 'builddir': builddir_name, @@ -2032,6 +2051,7 @@ def GenerateOutput(target_list, target_dicts, data, params): 'extra_commands': '', 'srcdir': srcdir, 'copy_archive_args': copy_archive_arguments, + 'makedep_args': makedep_arguments, } if flavor == 'mac': flock_command = './gyp-mac-tool flock' @@ -2045,6 +2065,14 @@ def GenerateOutput(target_list, target_dicts, data, params): header_params.update({ 'link_commands': LINK_COMMANDS_ANDROID, }) + elif flavor == 'os390': + copy_archive_arguments = '-fPR' + makedep_arguments = '-qmakedep=gcc' + header_params.update({ + 'copy_archive_args': copy_archive_arguments, + 'makedep_args': makedep_arguments, + 'link_commands': LINK_COMMANDS_OS390, + }) elif flavor == 'solaris': header_params.update({ 'flock': './gyp-flock-tool flock', diff --git a/third_party/gyp/generator/msvs.py b/third_party/gyp/generator/msvs.py index 705d5e17..8fe9e5af 100644 --- a/third_party/gyp/generator/msvs.py +++ b/third_party/gyp/generator/msvs.py @@ -306,9 +306,19 @@ def _ConfigWindowsTargetPlatformVersion(config_data, version): continue version = MSVSVersion._RegistryGetValue(key % ver, 'ProductVersion') or '' # Find a matching entry in sdk_dir\include. - names = sorted([x for x in os.listdir(r'%s\include' % sdk_dir) + expected_sdk_dir=r'%s\include' % sdk_dir + names = sorted([x for x in (os.listdir(expected_sdk_dir) + if os.path.isdir(expected_sdk_dir) + else [] + ) if x.startswith(version)], reverse=True) - return names[0] + if names: + return names[0] + else: + print >> sys.stdout, ( + 'Warning: No include files found for ' + 'detected Windows SDK version %s' % (version) + ) def _BuildCommandLineForRuleRaw(spec, cmd, cygwin_shell, has_input_path, @@ -2721,7 +2731,7 @@ def _GetMSBuildGlobalProperties(spec, version, guid, gyp_file_name): properties[0].append(['WindowsTargetPlatformVersion', str(msvs_windows_sdk_version)]) elif version.compatible_sdks: - raise GypError('%s requires any SDK of %o version, but non were found' % + raise GypError('%s requires any SDK of %s version, but none were found' % (version.description, version.compatible_sdks)) if platform_name == 'ARM': diff --git a/third_party/gyp/generator/ninja.py b/third_party/gyp/generator/ninja.py index 0555a4a9..3974a041 100644 --- a/third_party/gyp/generator/ninja.py +++ b/third_party/gyp/generator/ninja.py @@ -2311,15 +2311,22 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, 'stamp', description='STAMP $out', command='%s gyp-win-tool stamp $out' % sys.executable) - master_ninja.rule( - 'copy', - description='COPY $in $out', - command='%s gyp-win-tool recursive-mirror $in $out' % sys.executable) else: master_ninja.rule( 'stamp', description='STAMP $out', command='${postbuilds}touch $out') + if flavor == 'win': + master_ninja.rule( + 'copy', + description='COPY $in $out', + command='%s gyp-win-tool recursive-mirror $in $out' % sys.executable) + elif flavor == 'os390': + master_ninja.rule( + 'copy', + description='COPY $in $out', + command='rm -rf $out && cp -fRP $in $out') + else: master_ninja.rule( 'copy', description='COPY $in $out', diff --git a/third_party/gyp/mac_tool.py b/third_party/gyp/mac_tool.py index b0363cc3..0ad7e7a1 100755 --- a/third_party/gyp/mac_tool.py +++ b/third_party/gyp/mac_tool.py @@ -105,17 +105,21 @@ class MacTool(object): ibtool_section_re = re.compile(r'/\*.*\*/') ibtool_re = re.compile(r'.*note:.*is clipping its content') - ibtoolout = subprocess.Popen(args, stdout=subprocess.PIPE) + try: + stdout = subprocess.check_output(args) + except subprocess.CalledProcessError as e: + print(e.output) + raise current_section_header = None - for line in ibtoolout.stdout: + for line in stdout.splitlines(): if ibtool_section_re.match(line): current_section_header = line elif not ibtool_re.match(line): if current_section_header: - sys.stdout.write(current_section_header) + print(current_section_header) current_section_header = None - sys.stdout.write(line) - return ibtoolout.returncode + print(line) + return 0 def _ConvertToBinary(self, dest): subprocess.check_call([ diff --git a/third_party/protobuf.gypi b/third_party/protobuf.gypi index cbef3957..c61d3fea 100644 --- a/third_party/protobuf.gypi +++ b/third_party/protobuf.gypi @@ -44,6 +44,17 @@ '-Wno-unused-const-variable', '-Wno-unused-function', ], + 'cflags_cc': [ + '-frtti', + '-Wno-sign-compare', + '-Wno-unused-const-variable', + '-Wno-unused-function', + '-Wno-unused-parameter', + '-Wno-shadow', + '-Wno-tautological-undefined-compare', + '-Wno-conversion', + '-Wno-useless-cast', + ], }, 'targets': [ { diff --git a/third_party/stringencoders/LICENSE b/third_party/stringencoders/LICENSE deleted file mode 100644 index d03c4b21..00000000 --- a/third_party/stringencoders/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Nick Galbreath - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/third_party/stringencoders/src/config.h b/third_party/stringencoders/src/config.h deleted file mode 100644 index e69de29b..00000000 diff --git a/third_party/stringencoders/src/extern_c_begin.h b/third_party/stringencoders/src/extern_c_begin.h deleted file mode 100644 index 464277c3..00000000 --- a/third_party/stringencoders/src/extern_c_begin.h +++ /dev/null @@ -1,3 +0,0 @@ -#ifdef __cplusplus -extern "C" { -#endif diff --git a/third_party/stringencoders/src/extern_c_end.h b/third_party/stringencoders/src/extern_c_end.h deleted file mode 100644 index d4aa34d6..00000000 --- a/third_party/stringencoders/src/extern_c_end.h +++ /dev/null @@ -1,3 +0,0 @@ -#ifdef __cplusplus -} -#endif diff --git a/third_party/stringencoders/src/modp_b64.cpp b/third_party/stringencoders/src/modp_b64.cpp deleted file mode 100644 index 41ed1881..00000000 --- a/third_party/stringencoders/src/modp_b64.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/** - * \file modp_b64.c - *

- * MODP_B64 - High performance base64 encoder/decoder
- * https://github.com/client9/stringencoders
- *
- * Copyright © 2005-2016 Nick Galbreath
- * All rights reserved.
- * Released under MIT license. See LICENSE for details.
- * 
- */ - -/* - * If you are ripping this out of the library, comment out the next - * line and uncomment the next lines as approrpiate - */ -#include "config.h" - -/* public header */ -#include "modp_b64.h" - -/* if on motorola, sun, ibm; uncomment this */ -/* #define WORDS_BIGENDIAN 1 */ -/* else for Intel, Amd; uncomment this */ -/* #undef WORDS_BIGENDIAN */ - -#include "modp_b64_data.h" - -#define BADCHAR 0x01FFFFFF - -/** - * you can control if we use padding by commenting out this - * next line. However, I highly recommend you use padding and not - * using it should only be for compatibility with a 3rd party. - * Also, 'no padding' is not tested! - */ -#define DOPAD 1 - -/* - * if we aren't doing padding - * set the pad character to NULL - */ -#ifndef DOPAD -#undef CHARPAD -#define CHARPAD '\0' -#endif - -size_t modp_b64_encode(char* dest, const char* str, size_t len) -{ - size_t i = 0; - const uint8_t* s = (const uint8_t*)str; - uint8_t* p = (uint8_t*)dest; - - /* unsigned here is important! */ - /* uint8_t is fastest on G4, amd */ - /* uint32_t is fastest on Intel */ - uint32_t t1, t2, t3; - - if (len > 2) { - for (i = 0; i < len - 2; i += 3) { - t1 = s[i]; - t2 = s[i + 1]; - t3 = s[i + 2]; - *p++ = e0[t1]; - *p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)]; - *p++ = e1[((t2 & 0x0F) << 2) | ((t3 >> 6) & 0x03)]; - *p++ = e2[t3]; - } - } - - switch (len - i) { - case 0: - break; - case 1: - t1 = s[i]; - *p++ = e0[t1]; - *p++ = e1[(t1 & 0x03) << 4]; - *p++ = CHARPAD; - *p++ = CHARPAD; - break; - default: /* case 2 */ - t1 = s[i]; - t2 = s[i + 1]; - *p++ = e0[t1]; - *p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)]; - *p++ = e2[(t2 & 0x0F) << 2]; - *p++ = CHARPAD; - } - - *p = '\0'; - return (size_t)(p - (uint8_t*)dest); -} - -#ifdef WORDS_BIGENDIAN /* BIG ENDIAN -- SUN / IBM / MOTOROLA */ -size_t modp_b64_decode(char* dest, const char* src, size_t len) -{ - size_t i; - if (len == 0) - return 0; - -#ifdef DOPAD - /* if padding is used, then the message must be at least - 4 chars and be a multiple of 4. - there can be at most 2 pad chars at the end */ - if (len < 4 || (len % 4 != 0)) - return -1; - if (src[len - 1] == CHARPAD) { - len--; - if (src[len - 1] == CHARPAD) { - len--; - } - } -#endif /* DOPAD */ - - size_t leftover = len % 4; - size_t chunks = (leftover == 0) ? len / 4 - 1 : len / 4; - - uint8_t* p = (uint8_t*)dest; - uint32_t x = 0; - uint32_t* destInt = (uint32_t*)p; - uint32_t* srcInt = (uint32_t*)src; - uint32_t y = *srcInt++; - for (i = 0; i < chunks; ++i) { - x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] | d2[y >> 8 & 0xff] | d3[y & 0xff]; - - if (x >= BADCHAR) - return -1; - *destInt = x << 8; - p += 3; - destInt = (uint32_t*)p; - y = *srcInt++; - } - - switch (leftover) { - case 0: - x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] | d2[y >> 8 & 0xff] | d3[y & 0xff]; - if (x >= BADCHAR) - return -1; - *p++ = ((uint8_t*)&x)[1]; - *p++ = ((uint8_t*)&x)[2]; - *p = ((uint8_t*)&x)[3]; - return (chunks + 1) * 3; -#ifndef DOPAD - case 1: /* with padding this is an impossible case */ - x = d3[y >> 24]; - *p = (uint8_t)x; - break; -#endif - case 2: - x = d3[y >> 24] * 64 + d3[(y >> 16) & 0xff]; - *p = (uint8_t)(x >> 4); - break; - default: /* case 3 */ - x = (d3[y >> 24] * 64 + d3[(y >> 16) & 0xff]) * 64 + d3[(y >> 8) & 0xff]; - *p++ = (uint8_t)(x >> 10); - *p = (uint8_t)(x >> 2); - break; - } - - if (x >= BADCHAR) - return -1; - return 3 * chunks + (6 * leftover) / 8; -} - -#else /* LITTLE ENDIAN -- INTEL AND FRIENDS */ - -size_t modp_b64_decode(char* dest, const char* src, size_t len) -{ - size_t i; - size_t leftover; - size_t chunks; - - uint8_t* p; - uint32_t x; - uint32_t* destInt; - const uint32_t* srcInt = (const uint32_t*)src; - uint32_t y = *srcInt++; - - if (len == 0) - return 0; - -#ifdef DOPAD - /* - * if padding is used, then the message must be at least - * 4 chars and be a multiple of 4 - */ - if (len < 4 || (len % 4 != 0)) { - return (size_t)-1; /* error */ - } - /* there can be at most 2 pad chars at the end */ - if (src[len - 1] == CHARPAD) { - len--; - if (src[len - 1] == CHARPAD) { - len--; - } - } -#endif - - leftover = len % 4; - chunks = (leftover == 0) ? len / 4 - 1 : len / 4; - - p = (uint8_t*)dest; - x = 0; - destInt = (uint32_t*)p; - srcInt = (const uint32_t*)src; - y = *srcInt++; - for (i = 0; i < chunks; ++i) { - x = d0[y & 0xff] | d1[(y >> 8) & 0xff] | d2[(y >> 16) & 0xff] | d3[(y >> 24) & 0xff]; - - if (x >= BADCHAR) { - return (size_t)-1; - } - *destInt = x; - p += 3; - destInt = (uint32_t*)p; - y = *srcInt++; - } - - switch (leftover) { - case 0: - x = d0[y & 0xff] | d1[(y >> 8) & 0xff] | d2[(y >> 16) & 0xff] | d3[(y >> 24) & 0xff]; - - if (x >= BADCHAR) { - return (size_t)-1; - } - *p++ = ((uint8_t*)(&x))[0]; - *p++ = ((uint8_t*)(&x))[1]; - *p = ((uint8_t*)(&x))[2]; - return (chunks + 1) * 3; -#ifndef DOPAD - case 1: /* with padding this is an impossible case */ - x = d0[y & 0xff]; - *p = *((uint8_t*)(&x)); /* i.e. first char/byte in int */ - break; -#endif - case 2: /* case 2, 1 output byte */ - x = d0[y & 0xff] | d1[y >> 8 & 0xff]; - *p = *((uint8_t*)(&x)); /* i.e. first char */ - break; - default: /* case 3, 2 output bytes */ - x = d0[y & 0xff] | d1[y >> 8 & 0xff] | d2[y >> 16 & 0xff]; /* 0x3c */ - *p++ = ((uint8_t*)(&x))[0]; - *p = ((uint8_t*)(&x))[1]; - break; - } - - if (x >= BADCHAR) { - return (size_t)-1; - } - - return 3 * chunks + (6 * leftover) / 8; -} - -#endif /* if bigendian / else / endif */ diff --git a/third_party/stringencoders/src/modp_b64.h b/third_party/stringencoders/src/modp_b64.h deleted file mode 100644 index 3e03ac5e..00000000 --- a/third_party/stringencoders/src/modp_b64.h +++ /dev/null @@ -1,236 +0,0 @@ -/** - * \file modp_b64.h - * \brief High performance base 64 encode and decode - * - */ - -/* - * \file - *
- * High performance base64 encoder / decoder
- *
- * Copyright © 2005-2016 Nick Galbreath
- * All rights reserved.
- *
- * https://github.com/client9/stringencoders
- *
- * Released under MIT license.  See LICENSE for details.
- * 
- * - * This uses the standard base 64 alphabet. If you are planning - * to embed a base 64 encoding inside a URL use modp_b64w instead. - * - * ATTENTION: the algorithm may require ALIGNED strings. For Intel - * chips alignment doens't (perhaps a performance issues). But for - * Sparc and maybe ARM, use of unaligned strings can core dump. - * see https://github.com/client9/stringencoders/issues/1 - * see https://github.com/client9/stringencoders/issues/42 - */ - -#ifndef COM_MODP_STRINGENCODERS_B64 -#define COM_MODP_STRINGENCODERS_B64 - -#include "extern_c_begin.h" -#include "modp_stdint.h" - -/** - * \brief Encode a raw binary string into base 64. - * \param[out] dest should be allocated by the caller to contain - * at least modp_b64_encode_len(len) bytes (see below) - * This will contain the null-terminated b64 encoded result - * \param[in] src contains the bytes - * \param[in] len contains the number of bytes in the src - * \return length of the destination string plus the ending null byte - * i.e. the result will be equal to strlen(dest) + 1 - * - * Example - * - * \code - * char* src = ...; - * int srclen = ...; //the length of number of bytes in src - * char* dest = (char*) malloc(modp_b64_encode_len); - * int len = modp_b64_encode(dest, src, sourcelen); - * if (len == -1) { - * printf("Error\n"); - * } else { - * printf("b64 = %s\n", dest); - * } - * \endcode - * - */ -size_t modp_b64_encode(char* dest, const char* str, size_t len); - -/** - * Decode a base64 encoded string - * - * \param[out] dest should be allocated by the caller to contain at least - * len * 3 / 4 bytes. The destination cannot be the same as the source - * They must be different buffers. - * \param[in] src should contain exactly len bytes of b64 characters. - * if src contains -any- non-base characters (such as white - * space, -1 is returned. - * \param[in] len is the length of src - * - * \return the length (strlen) of the output, or -1 if unable to - * decode - * - * \code - * char* src = ...; - * int srclen = ...; // or if you don't know use strlen(src) - * char* dest = (char*) malloc(modp_b64_decode_len(srclen)); - * int len = modp_b64_decode(dest, src, sourcelen); - * if (len == -1) { error } - * \endcode - */ -size_t modp_b64_decode(char* dest, const char* src, size_t len); - -/** - * Given a source string of length len, this returns the amount of - * memory the destination string should have. - * - * remember, this is integer math - * 3 bytes turn into 4 chars - * ceiling[len / 3] * 4 + 1 - * - * +1 is for any extra null. - */ -#define modp_b64_encode_len(A) ((A + 2) / 3 * 4 + 1) - -/** - * Given a base64 string of length len, - * this returns the amount of memory required for output string - * It maybe be more than the actual number of bytes written. - * NOTE: remember this is integer math - * this allocates a bit more memory than traditional versions of b64 - * decode 4 chars turn into 3 bytes - * floor[len * 3/4] + 2 - */ -#define modp_b64_decode_len(A) (A / 4 * 3 + 2) - -/** - * Will return the strlen of the output from encoding. - * This may be less than the required number of bytes allocated. - * - * This allows you to 'deserialized' a struct - * \code - * char* b64encoded = "..."; - * int len = strlen(b64encoded); - * - * struct datastuff foo; - * if (modp_b64_encode_strlen(sizeof(struct datastuff)) != len) { - * // wrong size - * return false; - * } else { - * // safe to do; - * if (modp_b64_decode((char*) &foo, b64encoded, len) == -1) { - * // bad characters - * return false; - * } - * } - * // foo is filled out now - * \endcode - */ -#define modp_b64_encode_strlen(A) ((A + 2) / 3 * 4) - -#include "extern_c_end.h" - -#ifdef __cplusplus -#include -#include - -namespace modp { -/** \brief b64 encode a cstr with len - * - * \param[in] s the input string to encode - * \param[in] len the length of the input string - * \return a newly allocated b64 string. Empty if failed. - */ -inline std::string b64_encode(const char* s, size_t len) -{ - std::string x(modp_b64_encode_len(len), '\0'); - size_t d = modp_b64_encode(const_cast(x.data()), s, len); - if (d == (size_t)-1) { - x.clear(); - } else { - x.erase(d, std::string::npos); - } - return x; -} - -/** \brief b64 encode a cstr - * - * \param[in] s the input string to encode - * \return a newly allocated b64 string. Empty if failed. - */ -inline std::string b64_encode(const char* s) -{ - return b64_encode(s, strlen(s)); -} - -/** \brief b64 encode a const std::string - * - * \param[in] s the input string to encode - * \return a newly allocated b64 string. Empty if failed. - */ -inline std::string b64_encode(const std::string& s) -{ - return b64_encode(s.data(), s.size()); -} - -/** - * base 64 encode a string (self-modifing) - * - * This function is for C++ only (duh) - * - * \param[in,out] s the string to be decoded - * \return a reference to the input string - */ -inline std::string& b64_encode(std::string& s) -{ - std::string x(b64_encode(s.data(), s.size())); - s.swap(x); - return s; -} - -inline std::string b64_decode(const char* src, size_t len) -{ - std::string x(modp_b64_decode_len(len) + 1, '\0'); - size_t d = modp_b64_decode(const_cast(x.data()), src, len); - if (d == (size_t)-1) { - x.clear(); - } else { - x.erase(d, std::string::npos); - } - return x; -} - -inline std::string b64_decode(const char* src) -{ - return b64_decode(src, strlen(src)); -} - -/** - * base 64 decode a string (self-modifing) - * On failure, the string is empty. - * - * This function is for C++ only (duh) - * - * \param[in,out] s the string to be decoded - * \return a reference to the input string - */ -inline std::string& b64_decode(std::string& s) -{ - std::string x(b64_decode(s.data(), s.size())); - s.swap(x); - return s; -} - -inline std::string b64_decode(const std::string& s) -{ - return b64_decode(s.data(), s.size()); -} -} - -#endif /* __cplusplus */ - -#endif /* MODP_B64 */ diff --git a/third_party/stringencoders/src/modp_b64_data.h b/third_party/stringencoders/src/modp_b64_data.h deleted file mode 100644 index 34a0fa8b..00000000 --- a/third_party/stringencoders/src/modp_b64_data.h +++ /dev/null @@ -1,477 +0,0 @@ -#include "modp_stdint.h" -#define CHAR62 '+' -#define CHAR63 '/' -#define CHARPAD '=' -static const uint8_t e0[256] = { - 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', - 'C', 'C', 'D', 'D', 'D', 'D', 'E', 'E', 'E', 'E', - 'F', 'F', 'F', 'F', 'G', 'G', 'G', 'G', 'H', 'H', - 'H', 'H', 'I', 'I', 'I', 'I', 'J', 'J', 'J', 'J', - 'K', 'K', 'K', 'K', 'L', 'L', 'L', 'L', 'M', 'M', - 'M', 'M', 'N', 'N', 'N', 'N', 'O', 'O', 'O', 'O', - 'P', 'P', 'P', 'P', 'Q', 'Q', 'Q', 'Q', 'R', 'R', - 'R', 'R', 'S', 'S', 'S', 'S', 'T', 'T', 'T', 'T', - 'U', 'U', 'U', 'U', 'V', 'V', 'V', 'V', 'W', 'W', - 'W', 'W', 'X', 'X', 'X', 'X', 'Y', 'Y', 'Y', 'Y', - 'Z', 'Z', 'Z', 'Z', 'a', 'a', 'a', 'a', 'b', 'b', - 'b', 'b', 'c', 'c', 'c', 'c', 'd', 'd', 'd', 'd', - 'e', 'e', 'e', 'e', 'f', 'f', 'f', 'f', 'g', 'g', - 'g', 'g', 'h', 'h', 'h', 'h', 'i', 'i', 'i', 'i', - 'j', 'j', 'j', 'j', 'k', 'k', 'k', 'k', 'l', 'l', - 'l', 'l', 'm', 'm', 'm', 'm', 'n', 'n', 'n', 'n', - 'o', 'o', 'o', 'o', 'p', 'p', 'p', 'p', 'q', 'q', - 'q', 'q', 'r', 'r', 'r', 'r', 's', 's', 's', 's', - 't', 't', 't', 't', 'u', 'u', 'u', 'u', 'v', 'v', - 'v', 'v', 'w', 'w', 'w', 'w', 'x', 'x', 'x', 'x', - 'y', 'y', 'y', 'y', 'z', 'z', 'z', 'z', '0', '0', - '0', '0', '1', '1', '1', '1', '2', '2', '2', '2', - '3', '3', '3', '3', '4', '4', '4', '4', '5', '5', - '5', '5', '6', '6', '6', '6', '7', '7', '7', '7', - '8', '8', '8', '8', '9', '9', '9', '9', '+', '+', - '+', '+', '/', '/', '/', '/' -}; -static const uint8_t e1[256] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', - 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', - 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', - 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', '+', '/', 'A', 'B', 'C', 'D', 'E', 'F', - 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', - 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', - 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', - '4', '5', '6', '7', '8', '9', '+', '/', 'A', 'B', - 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', - 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', - 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', - 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - '+', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', - 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', - 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', - '6', '7', '8', '9', '+', '/' -}; -static const uint8_t e2[256] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', - 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', - 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', - 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', '+', '/', 'A', 'B', 'C', 'D', 'E', 'F', - 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', - 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', - 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', - '4', '5', '6', '7', '8', '9', '+', '/', 'A', 'B', - 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', - 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', - 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', - 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - '+', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', - 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', - 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', - '6', '7', '8', '9', '+', '/' -}; - - -#ifdef WORDS_BIGENDIAN - - -/* SPECIAL DECODE TABLES FOR BIG ENDIAN (IBM/MOTOROLA/SUN) CPUS */ - -static const uint32_t d0[256] = { - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x00f80000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00fc0000, - 0x00d00000, 0x00d40000, 0x00d80000, 0x00dc0000, 0x00e00000, 0x00e40000, - 0x00e80000, 0x00ec0000, 0x00f00000, 0x00f40000, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, - 0x00040000, 0x00080000, 0x000c0000, 0x00100000, 0x00140000, 0x00180000, - 0x001c0000, 0x00200000, 0x00240000, 0x00280000, 0x002c0000, 0x00300000, - 0x00340000, 0x00380000, 0x003c0000, 0x00400000, 0x00440000, 0x00480000, - 0x004c0000, 0x00500000, 0x00540000, 0x00580000, 0x005c0000, 0x00600000, - 0x00640000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x00680000, 0x006c0000, 0x00700000, 0x00740000, 0x00780000, - 0x007c0000, 0x00800000, 0x00840000, 0x00880000, 0x008c0000, 0x00900000, - 0x00940000, 0x00980000, 0x009c0000, 0x00a00000, 0x00a40000, 0x00a80000, - 0x00ac0000, 0x00b00000, 0x00b40000, 0x00b80000, 0x00bc0000, 0x00c00000, - 0x00c40000, 0x00c80000, 0x00cc0000, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff -}; - - -static const uint32_t d1[256] = { - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x0003e000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0003f000, - 0x00034000, 0x00035000, 0x00036000, 0x00037000, 0x00038000, 0x00039000, - 0x0003a000, 0x0003b000, 0x0003c000, 0x0003d000, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, - 0x00001000, 0x00002000, 0x00003000, 0x00004000, 0x00005000, 0x00006000, - 0x00007000, 0x00008000, 0x00009000, 0x0000a000, 0x0000b000, 0x0000c000, - 0x0000d000, 0x0000e000, 0x0000f000, 0x00010000, 0x00011000, 0x00012000, - 0x00013000, 0x00014000, 0x00015000, 0x00016000, 0x00017000, 0x00018000, - 0x00019000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x0001a000, 0x0001b000, 0x0001c000, 0x0001d000, 0x0001e000, - 0x0001f000, 0x00020000, 0x00021000, 0x00022000, 0x00023000, 0x00024000, - 0x00025000, 0x00026000, 0x00027000, 0x00028000, 0x00029000, 0x0002a000, - 0x0002b000, 0x0002c000, 0x0002d000, 0x0002e000, 0x0002f000, 0x00030000, - 0x00031000, 0x00032000, 0x00033000, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff -}; - - -static const uint32_t d2[256] = { - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x00000f80, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000fc0, - 0x00000d00, 0x00000d40, 0x00000d80, 0x00000dc0, 0x00000e00, 0x00000e40, - 0x00000e80, 0x00000ec0, 0x00000f00, 0x00000f40, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, - 0x00000040, 0x00000080, 0x000000c0, 0x00000100, 0x00000140, 0x00000180, - 0x000001c0, 0x00000200, 0x00000240, 0x00000280, 0x000002c0, 0x00000300, - 0x00000340, 0x00000380, 0x000003c0, 0x00000400, 0x00000440, 0x00000480, - 0x000004c0, 0x00000500, 0x00000540, 0x00000580, 0x000005c0, 0x00000600, - 0x00000640, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x00000680, 0x000006c0, 0x00000700, 0x00000740, 0x00000780, - 0x000007c0, 0x00000800, 0x00000840, 0x00000880, 0x000008c0, 0x00000900, - 0x00000940, 0x00000980, 0x000009c0, 0x00000a00, 0x00000a40, 0x00000a80, - 0x00000ac0, 0x00000b00, 0x00000b40, 0x00000b80, 0x00000bc0, 0x00000c00, - 0x00000c40, 0x00000c80, 0x00000cc0, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff -}; - - -static const uint32_t d3[256] = { - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x0000003e, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000003f, - 0x00000034, 0x00000035, 0x00000036, 0x00000037, 0x00000038, 0x00000039, - 0x0000003a, 0x0000003b, 0x0000003c, 0x0000003d, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, - 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, - 0x00000007, 0x00000008, 0x00000009, 0x0000000a, 0x0000000b, 0x0000000c, - 0x0000000d, 0x0000000e, 0x0000000f, 0x00000010, 0x00000011, 0x00000012, - 0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017, 0x00000018, - 0x00000019, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x0000001a, 0x0000001b, 0x0000001c, 0x0000001d, 0x0000001e, - 0x0000001f, 0x00000020, 0x00000021, 0x00000022, 0x00000023, 0x00000024, - 0x00000025, 0x00000026, 0x00000027, 0x00000028, 0x00000029, 0x0000002a, - 0x0000002b, 0x0000002c, 0x0000002d, 0x0000002e, 0x0000002f, 0x00000030, - 0x00000031, 0x00000032, 0x00000033, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff -}; - - -#else - - -/* SPECIAL DECODE TABLES FOR LITTLE ENDIAN (INTEL) CPUS */ - -static const uint32_t d0[256] = { - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x000000f8, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x000000fc, - 0x000000d0, 0x000000d4, 0x000000d8, 0x000000dc, 0x000000e0, 0x000000e4, - 0x000000e8, 0x000000ec, 0x000000f0, 0x000000f4, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, - 0x00000004, 0x00000008, 0x0000000c, 0x00000010, 0x00000014, 0x00000018, - 0x0000001c, 0x00000020, 0x00000024, 0x00000028, 0x0000002c, 0x00000030, - 0x00000034, 0x00000038, 0x0000003c, 0x00000040, 0x00000044, 0x00000048, - 0x0000004c, 0x00000050, 0x00000054, 0x00000058, 0x0000005c, 0x00000060, - 0x00000064, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x00000068, 0x0000006c, 0x00000070, 0x00000074, 0x00000078, - 0x0000007c, 0x00000080, 0x00000084, 0x00000088, 0x0000008c, 0x00000090, - 0x00000094, 0x00000098, 0x0000009c, 0x000000a0, 0x000000a4, 0x000000a8, - 0x000000ac, 0x000000b0, 0x000000b4, 0x000000b8, 0x000000bc, 0x000000c0, - 0x000000c4, 0x000000c8, 0x000000cc, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff -}; - - -static const uint32_t d1[256] = { - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x0000e003, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000f003, - 0x00004003, 0x00005003, 0x00006003, 0x00007003, 0x00008003, 0x00009003, - 0x0000a003, 0x0000b003, 0x0000c003, 0x0000d003, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, - 0x00001000, 0x00002000, 0x00003000, 0x00004000, 0x00005000, 0x00006000, - 0x00007000, 0x00008000, 0x00009000, 0x0000a000, 0x0000b000, 0x0000c000, - 0x0000d000, 0x0000e000, 0x0000f000, 0x00000001, 0x00001001, 0x00002001, - 0x00003001, 0x00004001, 0x00005001, 0x00006001, 0x00007001, 0x00008001, - 0x00009001, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x0000a001, 0x0000b001, 0x0000c001, 0x0000d001, 0x0000e001, - 0x0000f001, 0x00000002, 0x00001002, 0x00002002, 0x00003002, 0x00004002, - 0x00005002, 0x00006002, 0x00007002, 0x00008002, 0x00009002, 0x0000a002, - 0x0000b002, 0x0000c002, 0x0000d002, 0x0000e002, 0x0000f002, 0x00000003, - 0x00001003, 0x00002003, 0x00003003, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff -}; - - -static const uint32_t d2[256] = { - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x00800f00, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00c00f00, - 0x00000d00, 0x00400d00, 0x00800d00, 0x00c00d00, 0x00000e00, 0x00400e00, - 0x00800e00, 0x00c00e00, 0x00000f00, 0x00400f00, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, - 0x00400000, 0x00800000, 0x00c00000, 0x00000100, 0x00400100, 0x00800100, - 0x00c00100, 0x00000200, 0x00400200, 0x00800200, 0x00c00200, 0x00000300, - 0x00400300, 0x00800300, 0x00c00300, 0x00000400, 0x00400400, 0x00800400, - 0x00c00400, 0x00000500, 0x00400500, 0x00800500, 0x00c00500, 0x00000600, - 0x00400600, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x00800600, 0x00c00600, 0x00000700, 0x00400700, 0x00800700, - 0x00c00700, 0x00000800, 0x00400800, 0x00800800, 0x00c00800, 0x00000900, - 0x00400900, 0x00800900, 0x00c00900, 0x00000a00, 0x00400a00, 0x00800a00, - 0x00c00a00, 0x00000b00, 0x00400b00, 0x00800b00, 0x00c00b00, 0x00000c00, - 0x00400c00, 0x00800c00, 0x00c00c00, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff -}; - - -static const uint32_t d3[256] = { - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x003e0000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x003f0000, - 0x00340000, 0x00350000, 0x00360000, 0x00370000, 0x00380000, 0x00390000, - 0x003a0000, 0x003b0000, 0x003c0000, 0x003d0000, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, - 0x00010000, 0x00020000, 0x00030000, 0x00040000, 0x00050000, 0x00060000, - 0x00070000, 0x00080000, 0x00090000, 0x000a0000, 0x000b0000, 0x000c0000, - 0x000d0000, 0x000e0000, 0x000f0000, 0x00100000, 0x00110000, 0x00120000, - 0x00130000, 0x00140000, 0x00150000, 0x00160000, 0x00170000, 0x00180000, - 0x00190000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x001a0000, 0x001b0000, 0x001c0000, 0x001d0000, 0x001e0000, - 0x001f0000, 0x00200000, 0x00210000, 0x00220000, 0x00230000, 0x00240000, - 0x00250000, 0x00260000, 0x00270000, 0x00280000, 0x00290000, 0x002a0000, - 0x002b0000, 0x002c0000, 0x002d0000, 0x002e0000, 0x002f0000, 0x00300000, - 0x00310000, 0x00320000, 0x00330000, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff -}; - - -#endif diff --git a/third_party/stringencoders/src/modp_b64w.cpp b/third_party/stringencoders/src/modp_b64w.cpp deleted file mode 100644 index 45fa360d..00000000 --- a/third_party/stringencoders/src/modp_b64w.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/** - * \file modp_b64w.c - *
- * MODP_B64 - High performance base64 encoder/decoder
- * https://github.com/client9/stringencoders
- *
- * Copyright © 2005-2016 Nick Galbreath
- * All rights reserved.
- * Released under MIT license. See LICENSE for details.
- * 
- */ - -/* - * If you are ripping this out of the library, comment out the next - * line and uncomment the next lines as approrpiate - */ -#include "config.h" - -/* public header */ -#include "modp_b64w.h" - -/* if on motorola, sun, ibm; uncomment this */ -/* #define WORDS_BIGENDIAN 1 */ -/* else for Intel, Amd; uncomment this */ -/* #undef WORDS_BIGENDIAN */ - -#include "modp_b64w_data.h" - -#define BADCHAR 0x01FFFFFF - -/** - * you can control if we use padding by commenting out this - * next line. However, I highly recommend you use padding and not - * using it should only be for compatibility with a 3rd party. - * Also, 'no padding' is not tested! - */ -#define DOPAD 1 - -/* - * if we aren't doing padding - * set the pad character to NULL - */ -#ifndef DOPAD -#undef CHARPAD -#define CHARPAD '\0' -#endif - -size_t modp_b64w_encode(char* dest, const char* str, size_t len) -{ - size_t i = 0; - const uint8_t* s = (const uint8_t*)str; - uint8_t* p = (uint8_t*)dest; - - /* unsigned here is important! */ - /* uint8_t is fastest on G4, amd */ - /* uint32_t is fastest on Intel */ - uint32_t t1, t2, t3; - - if (len > 2) { - for (i = 0; i < len - 2; i += 3) { - t1 = s[i]; - t2 = s[i + 1]; - t3 = s[i + 2]; - *p++ = e0[t1]; - *p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)]; - *p++ = e1[((t2 & 0x0F) << 2) | ((t3 >> 6) & 0x03)]; - *p++ = e2[t3]; - } - } - - switch (len - i) { - case 0: - break; - case 1: - t1 = s[i]; - *p++ = e0[t1]; - *p++ = e1[(t1 & 0x03) << 4]; - *p++ = CHARPAD; - *p++ = CHARPAD; - break; - default: /* case 2 */ - t1 = s[i]; - t2 = s[i + 1]; - *p++ = e0[t1]; - *p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)]; - *p++ = e2[(t2 & 0x0F) << 2]; - *p++ = CHARPAD; - } - - *p = '\0'; - return (size_t)(p - (uint8_t*)dest); -} - -#ifdef WORDS_BIGENDIAN /* BIG ENDIAN -- SUN / IBM / MOTOROLA */ -size_t modp_b64w_decode(char* dest, const char* src, size_t len) -{ - size_t i; - if (len == 0) - return 0; - -#ifdef DOPAD - /* if padding is used, then the message must be at least - 4 chars and be a multiple of 4. - there can be at most 2 pad chars at the end */ - if (len < 4 || (len % 4 != 0)) - return -1; - if (src[len - 1] == CHARPAD) { - len--; - if (src[len - 1] == CHARPAD) { - len--; - } - } -#endif /* DOPAD */ - - size_t leftover = len % 4; - size_t chunks = (leftover == 0) ? len / 4 - 1 : len / 4; - - uint8_t* p = (uint8_t*)dest; - uint32_t x = 0; - uint32_t* destInt = (uint32_t*)p; - uint32_t* srcInt = (uint32_t*)src; - uint32_t y = *srcInt++; - for (i = 0; i < chunks; ++i) { - x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] | d2[y >> 8 & 0xff] | d3[y & 0xff]; - - if (x >= BADCHAR) - return -1; - *destInt = x << 8; - p += 3; - destInt = (uint32_t*)p; - y = *srcInt++; - } - - switch (leftover) { - case 0: - x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] | d2[y >> 8 & 0xff] | d3[y & 0xff]; - if (x >= BADCHAR) - return -1; - *p++ = ((uint8_t*)&x)[1]; - *p++ = ((uint8_t*)&x)[2]; - *p = ((uint8_t*)&x)[3]; - return (chunks + 1) * 3; -#ifndef DOPAD - case 1: /* with padding this is an impossible case */ - x = d3[y >> 24]; - *p = (uint8_t)x; - break; -#endif - case 2: - x = d3[y >> 24] * 64 + d3[(y >> 16) & 0xff]; - *p = (uint8_t)(x >> 4); - break; - default: /* case 3 */ - x = (d3[y >> 24] * 64 + d3[(y >> 16) & 0xff]) * 64 + d3[(y >> 8) & 0xff]; - *p++ = (uint8_t)(x >> 10); - *p = (uint8_t)(x >> 2); - break; - } - - if (x >= BADCHAR) - return -1; - return 3 * chunks + (6 * leftover) / 8; -} - -#else /* LITTLE ENDIAN -- INTEL AND FRIENDS */ - -size_t modp_b64w_decode(char* dest, const char* src, size_t len) -{ - size_t i; - size_t leftover; - size_t chunks; - - uint8_t* p; - uint32_t x; - uint32_t* destInt; - const uint32_t* srcInt = (const uint32_t*)src; - uint32_t y = *srcInt++; - - if (len == 0) - return 0; - -#ifdef DOPAD - /* - * if padding is used, then the message must be at least - * 4 chars and be a multiple of 4 - */ - if (len < 4 || (len % 4 != 0)) { - return (size_t)-1; /* error */ - } - /* there can be at most 2 pad chars at the end */ - if (src[len - 1] == CHARPAD) { - len--; - if (src[len - 1] == CHARPAD) { - len--; - } - } -#endif - - leftover = len % 4; - chunks = (leftover == 0) ? len / 4 - 1 : len / 4; - - p = (uint8_t*)dest; - x = 0; - destInt = (uint32_t*)p; - srcInt = (const uint32_t*)src; - y = *srcInt++; - for (i = 0; i < chunks; ++i) { - x = d0[y & 0xff] | d1[(y >> 8) & 0xff] | d2[(y >> 16) & 0xff] | d3[(y >> 24) & 0xff]; - - if (x >= BADCHAR) { - return (size_t)-1; - } - *destInt = x; - p += 3; - destInt = (uint32_t*)p; - y = *srcInt++; - } - - switch (leftover) { - case 0: - x = d0[y & 0xff] | d1[(y >> 8) & 0xff] | d2[(y >> 16) & 0xff] | d3[(y >> 24) & 0xff]; - - if (x >= BADCHAR) { - return (size_t)-1; - } - *p++ = ((uint8_t*)(&x))[0]; - *p++ = ((uint8_t*)(&x))[1]; - *p = ((uint8_t*)(&x))[2]; - return (chunks + 1) * 3; -#ifndef DOPAD - case 1: /* with padding this is an impossible case */ - x = d0[y & 0xff]; - *p = *((uint8_t*)(&x)); /* i.e. first char/byte in int */ - break; -#endif - case 2: /* case 2, 1 output byte */ - x = d0[y & 0xff] | d1[y >> 8 & 0xff]; - *p = *((uint8_t*)(&x)); /* i.e. first char */ - break; - default: /* case 3, 2 output bytes */ - x = d0[y & 0xff] | d1[y >> 8 & 0xff] | d2[y >> 16 & 0xff]; /* 0x3c */ - *p++ = ((uint8_t*)(&x))[0]; - *p = ((uint8_t*)(&x))[1]; - break; - } - - if (x >= BADCHAR) { - return (size_t)-1; - } - - return 3 * chunks + (6 * leftover) / 8; -} - -#endif /* if bigendian / else / endif */ diff --git a/third_party/stringencoders/src/modp_b64w.h b/third_party/stringencoders/src/modp_b64w.h deleted file mode 100644 index 08208678..00000000 --- a/third_party/stringencoders/src/modp_b64w.h +++ /dev/null @@ -1,231 +0,0 @@ -/** - *
- * High performance WEB-SAFE base64 encoder / decoder
- *
- * Copyright © 2005-2016 Nick Galbreath -- nickg [at] client9 [dot] com
- * All rights reserved.
- *
- * https://github.com/client9/stringencoders/
- *
- * Released under MIT license.  See LICENSE for details.
- * 
- * - * This uses a "URL-safe" or "WEB-safe" encoding. The standard - * base 64 encoding uses the characters '+', '/' and '=' have special - * restrictions when used inside a URL. - * - * This uses "+" to "-", "/" to "_", and "=" to "." as the replacement - * alphabet. - * - * It's easy to change this to use "URL safe" characters and to remove - * padding. See the modp_b64.c source code for details. - * - */ - -#ifndef COM_MODP_STRINGENCODERS_B64W -#define COM_MODP_STRINGENCODERS_B64W - -#include "extern_c_begin.h" -#include "modp_stdint.h" - -/** - * \brief Encode a raw binary string into web-safe base 64. - * \param[out] dest should be allocated by the caller to contain - * at least modp_b64w_encode_len(len) bytes (see below) - * This will contain the null-terminated b64w encoded result - * \param[in] src contains the bytes - * \param[in] len contains the number of bytes in the src - * \return length of the destination string plus the ending null byte - * i.e. the result will be equal to strlen(dest) + 1 - * - * Example - * - * \code - * char* src = ...; - * int srclen = ...; //the length of number of bytes in src - * char* dest = (char*) malloc(modp_b64w_encode_len); - * int len = modp_b64w_encode(dest, src, sourcelen); - * if (len == -1) { - * printf("Error\n"); - * } else { - * printf("b64w = %s\n", dest); - * } - * \endcode - * - */ -size_t modp_b64w_encode(char* dest, const char* src, size_t len); - -/** - * \brief Decode a web-safe base64 encoded string - * - * \param[out] dest should be allocated by the caller to contain at least - * len * 3 / 4 bytes. - * \param[in] src should contain exactly len bytes of b64w characters. - * if src contains -any- non-base characters (such as white - * space, -1 is returned. - * \param[in] len is the length of src - * - * \return the length (strlen) of the output, or -1 if unable to - * decode - * - * \code - * char* src = ...; - * int srclen = ...; // or if you don't know use strlen(src) - * char* dest = (char*) malloc(modp_b64w_decode_len(srclen)); - * int len = modp_b64w_decode(dest, src, sourcelen); - * if (len == -1) { error } - * \endcode - */ -size_t modp_b64w_decode(char* dest, const char* src, size_t len); - -/** - * Given a source string of length len, this returns the amount of - * memory the destination string should have. - * - * remember, this is integer math - * 3 bytes turn into 4 chars - * ceiling[len / 3] * 4 + 1 - * - * +1 is for any extra null. - */ -#define modp_b64w_encode_len(A) ((A + 2) / 3 * 4 + 1) - -/** - * Given a base64 string of length len, - * this returns the amount of memory required for output string - * It maybe be more than the actual number of bytes written. - * NOTE: remember this is integer math - * this allocates a bit more memory than traditional versions of b64w - * decode 4 chars turn into 3 bytes - * floor[len * 3/4] + 2 - */ -#define modp_b64w_decode_len(A) (A / 4 * 3 + 2) - -/** - * Will return the strlen of the output from encoding. - * This may be less than the required number of bytes allocated. - * - * This allows you to 'deserialized' a struct: - * \code - * char* b64wencoded = "..."; - * int len = strlen(b64wencoded); - * - * struct datastuff foo; - * if (modp_b64w_encode_strlen(sizeof(struct datastuff)) != len) { - * // wrong size - * return false; - * } else { - * // safe to do; - * if (modp_b64w_decode((char*) &foo, b64wencoded, len) == -1) { - * // bad characters - * return false; - * } - * } - * // foo is filled out now - * \endcode - */ -#define modp_b64w_encode_strlen(A) ((A + 2) / 3 * 4) - -#include "extern_c_end.h" - -#ifdef __cplusplus -#include -#include - -namespace modp { - -/** \brief b64w encode a cstr with len - * - * \param[in] s the input string to encode - * \param[in] len the length of the input string - * \return a newly allocated b64w string. Empty if failed. - */ -inline std::string b64w_encode(const char* s, size_t len) -{ - std::string x(modp_b64w_encode_len(len), '\0'); - size_t d = modp_b64w_encode(const_cast(x.data()), s, len); - if (d == (size_t)-1) { - x.clear(); - } else { - x.erase(d, std::string::npos); - } - return x; -} - -/** \brief b64w encode a cstr - * - * \param[in] s the input string to encode - * \return a newly allocated b64w string. Empty if failed. - */ -inline std::string b64w_encode(const char* s) -{ - return b64w_encode(s, strlen(s)); -} - -/** \brief b64w encode a const std::string - * - * \param[in] s the input string to encode - * \return a newly allocated b64w string. Empty if failed. - */ -inline std::string b64w_encode(const std::string& s) -{ - return b64w_encode(s.data(), s.size()); -} - -/** \brief self-modifing b64w encode - * - * web-safe base 64 decode a string (self-modifing) - * On failure, the string is empty. - * - * \param[in,out] s the string to be decoded - * \return a reference to the input string - */ -inline std::string& b64w_encode(std::string& s) -{ - std::string x(b64w_encode(s.data(), s.size())); - s.swap(x); - return s; -} - -inline std::string b64w_decode(const char* src, size_t len) -{ - std::string x(modp_b64w_decode_len(len) + 1, '\0'); - size_t d = modp_b64w_decode(const_cast(x.data()), src, len); - if (d == (size_t)-1) { - x.clear(); - } else { - x.erase(d, std::string::npos); - } - return x; -} - -inline std::string b64w_decode(const char* src) -{ - return b64w_decode(src, strlen(src)); -} - -/** - * base 64 decode a string (self-modifing) - * On failure, the string is empty. - * - * This function is for C++ only (duh) - * - * \param[in,out] s the string to be decoded - * \return a reference to the input string - */ -inline std::string& b64w_decode(std::string& s) -{ - std::string x(b64w_decode(s.data(), s.size())); - s.swap(x); - return s; -} - -inline std::string b64w_decode(const std::string& s) -{ - return b64w_decode(s.data(), s.size()); -} -} - -#endif /* __cplusplus */ - -#endif /* MODP_B64W */ diff --git a/third_party/stringencoders/src/modp_b64w_data.h b/third_party/stringencoders/src/modp_b64w_data.h deleted file mode 100644 index 6698c2fa..00000000 --- a/third_party/stringencoders/src/modp_b64w_data.h +++ /dev/null @@ -1,477 +0,0 @@ -#include "modp_stdint.h" -#define CHAR62 '-' -#define CHAR63 '_' -#define CHARPAD '=' -static const uint8_t e0[256] = { - 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', - 'C', 'C', 'D', 'D', 'D', 'D', 'E', 'E', 'E', 'E', - 'F', 'F', 'F', 'F', 'G', 'G', 'G', 'G', 'H', 'H', - 'H', 'H', 'I', 'I', 'I', 'I', 'J', 'J', 'J', 'J', - 'K', 'K', 'K', 'K', 'L', 'L', 'L', 'L', 'M', 'M', - 'M', 'M', 'N', 'N', 'N', 'N', 'O', 'O', 'O', 'O', - 'P', 'P', 'P', 'P', 'Q', 'Q', 'Q', 'Q', 'R', 'R', - 'R', 'R', 'S', 'S', 'S', 'S', 'T', 'T', 'T', 'T', - 'U', 'U', 'U', 'U', 'V', 'V', 'V', 'V', 'W', 'W', - 'W', 'W', 'X', 'X', 'X', 'X', 'Y', 'Y', 'Y', 'Y', - 'Z', 'Z', 'Z', 'Z', 'a', 'a', 'a', 'a', 'b', 'b', - 'b', 'b', 'c', 'c', 'c', 'c', 'd', 'd', 'd', 'd', - 'e', 'e', 'e', 'e', 'f', 'f', 'f', 'f', 'g', 'g', - 'g', 'g', 'h', 'h', 'h', 'h', 'i', 'i', 'i', 'i', - 'j', 'j', 'j', 'j', 'k', 'k', 'k', 'k', 'l', 'l', - 'l', 'l', 'm', 'm', 'm', 'm', 'n', 'n', 'n', 'n', - 'o', 'o', 'o', 'o', 'p', 'p', 'p', 'p', 'q', 'q', - 'q', 'q', 'r', 'r', 'r', 'r', 's', 's', 's', 's', - 't', 't', 't', 't', 'u', 'u', 'u', 'u', 'v', 'v', - 'v', 'v', 'w', 'w', 'w', 'w', 'x', 'x', 'x', 'x', - 'y', 'y', 'y', 'y', 'z', 'z', 'z', 'z', '0', '0', - '0', '0', '1', '1', '1', '1', '2', '2', '2', '2', - '3', '3', '3', '3', '4', '4', '4', '4', '5', '5', - '5', '5', '6', '6', '6', '6', '7', '7', '7', '7', - '8', '8', '8', '8', '9', '9', '9', '9', '-', '-', - '-', '-', '_', '_', '_', '_' -}; -static const uint8_t e1[256] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', - 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', - 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', - 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', '-', '_', 'A', 'B', 'C', 'D', 'E', 'F', - 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', - 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', - 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', - '4', '5', '6', '7', '8', '9', '-', '_', 'A', 'B', - 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', - 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', - 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', - 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - '-', '_', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', - 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', - 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', - '6', '7', '8', '9', '-', '_' -}; -static const uint8_t e2[256] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', - 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', - 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', - 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', '-', '_', 'A', 'B', 'C', 'D', 'E', 'F', - 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', - 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', - 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', - '4', '5', '6', '7', '8', '9', '-', '_', 'A', 'B', - 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', - 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', - 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', - 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - '-', '_', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', - 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', - 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', - '6', '7', '8', '9', '-', '_' -}; - - -#ifdef WORDS_BIGENDIAN - - -/* SPECIAL DECODE TABLES FOR BIG ENDIAN (IBM/MOTOROLA/SUN) CPUS */ - -static const uint32_t d0[256] = { - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00f80000, 0x01ffffff, 0x01ffffff, - 0x00d00000, 0x00d40000, 0x00d80000, 0x00dc0000, 0x00e00000, 0x00e40000, - 0x00e80000, 0x00ec0000, 0x00f00000, 0x00f40000, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, - 0x00040000, 0x00080000, 0x000c0000, 0x00100000, 0x00140000, 0x00180000, - 0x001c0000, 0x00200000, 0x00240000, 0x00280000, 0x002c0000, 0x00300000, - 0x00340000, 0x00380000, 0x003c0000, 0x00400000, 0x00440000, 0x00480000, - 0x004c0000, 0x00500000, 0x00540000, 0x00580000, 0x005c0000, 0x00600000, - 0x00640000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00fc0000, - 0x01ffffff, 0x00680000, 0x006c0000, 0x00700000, 0x00740000, 0x00780000, - 0x007c0000, 0x00800000, 0x00840000, 0x00880000, 0x008c0000, 0x00900000, - 0x00940000, 0x00980000, 0x009c0000, 0x00a00000, 0x00a40000, 0x00a80000, - 0x00ac0000, 0x00b00000, 0x00b40000, 0x00b80000, 0x00bc0000, 0x00c00000, - 0x00c40000, 0x00c80000, 0x00cc0000, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff -}; - - -static const uint32_t d1[256] = { - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0003e000, 0x01ffffff, 0x01ffffff, - 0x00034000, 0x00035000, 0x00036000, 0x00037000, 0x00038000, 0x00039000, - 0x0003a000, 0x0003b000, 0x0003c000, 0x0003d000, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, - 0x00001000, 0x00002000, 0x00003000, 0x00004000, 0x00005000, 0x00006000, - 0x00007000, 0x00008000, 0x00009000, 0x0000a000, 0x0000b000, 0x0000c000, - 0x0000d000, 0x0000e000, 0x0000f000, 0x00010000, 0x00011000, 0x00012000, - 0x00013000, 0x00014000, 0x00015000, 0x00016000, 0x00017000, 0x00018000, - 0x00019000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0003f000, - 0x01ffffff, 0x0001a000, 0x0001b000, 0x0001c000, 0x0001d000, 0x0001e000, - 0x0001f000, 0x00020000, 0x00021000, 0x00022000, 0x00023000, 0x00024000, - 0x00025000, 0x00026000, 0x00027000, 0x00028000, 0x00029000, 0x0002a000, - 0x0002b000, 0x0002c000, 0x0002d000, 0x0002e000, 0x0002f000, 0x00030000, - 0x00031000, 0x00032000, 0x00033000, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff -}; - - -static const uint32_t d2[256] = { - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000f80, 0x01ffffff, 0x01ffffff, - 0x00000d00, 0x00000d40, 0x00000d80, 0x00000dc0, 0x00000e00, 0x00000e40, - 0x00000e80, 0x00000ec0, 0x00000f00, 0x00000f40, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, - 0x00000040, 0x00000080, 0x000000c0, 0x00000100, 0x00000140, 0x00000180, - 0x000001c0, 0x00000200, 0x00000240, 0x00000280, 0x000002c0, 0x00000300, - 0x00000340, 0x00000380, 0x000003c0, 0x00000400, 0x00000440, 0x00000480, - 0x000004c0, 0x00000500, 0x00000540, 0x00000580, 0x000005c0, 0x00000600, - 0x00000640, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000fc0, - 0x01ffffff, 0x00000680, 0x000006c0, 0x00000700, 0x00000740, 0x00000780, - 0x000007c0, 0x00000800, 0x00000840, 0x00000880, 0x000008c0, 0x00000900, - 0x00000940, 0x00000980, 0x000009c0, 0x00000a00, 0x00000a40, 0x00000a80, - 0x00000ac0, 0x00000b00, 0x00000b40, 0x00000b80, 0x00000bc0, 0x00000c00, - 0x00000c40, 0x00000c80, 0x00000cc0, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff -}; - - -static const uint32_t d3[256] = { - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000003e, 0x01ffffff, 0x01ffffff, - 0x00000034, 0x00000035, 0x00000036, 0x00000037, 0x00000038, 0x00000039, - 0x0000003a, 0x0000003b, 0x0000003c, 0x0000003d, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, - 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, - 0x00000007, 0x00000008, 0x00000009, 0x0000000a, 0x0000000b, 0x0000000c, - 0x0000000d, 0x0000000e, 0x0000000f, 0x00000010, 0x00000011, 0x00000012, - 0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017, 0x00000018, - 0x00000019, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000003f, - 0x01ffffff, 0x0000001a, 0x0000001b, 0x0000001c, 0x0000001d, 0x0000001e, - 0x0000001f, 0x00000020, 0x00000021, 0x00000022, 0x00000023, 0x00000024, - 0x00000025, 0x00000026, 0x00000027, 0x00000028, 0x00000029, 0x0000002a, - 0x0000002b, 0x0000002c, 0x0000002d, 0x0000002e, 0x0000002f, 0x00000030, - 0x00000031, 0x00000032, 0x00000033, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff -}; - - -#else - - -/* SPECIAL DECODE TABLES FOR LITTLE ENDIAN (INTEL) CPUS */ - -static const uint32_t d0[256] = { - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x000000f8, 0x01ffffff, 0x01ffffff, - 0x000000d0, 0x000000d4, 0x000000d8, 0x000000dc, 0x000000e0, 0x000000e4, - 0x000000e8, 0x000000ec, 0x000000f0, 0x000000f4, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, - 0x00000004, 0x00000008, 0x0000000c, 0x00000010, 0x00000014, 0x00000018, - 0x0000001c, 0x00000020, 0x00000024, 0x00000028, 0x0000002c, 0x00000030, - 0x00000034, 0x00000038, 0x0000003c, 0x00000040, 0x00000044, 0x00000048, - 0x0000004c, 0x00000050, 0x00000054, 0x00000058, 0x0000005c, 0x00000060, - 0x00000064, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x000000fc, - 0x01ffffff, 0x00000068, 0x0000006c, 0x00000070, 0x00000074, 0x00000078, - 0x0000007c, 0x00000080, 0x00000084, 0x00000088, 0x0000008c, 0x00000090, - 0x00000094, 0x00000098, 0x0000009c, 0x000000a0, 0x000000a4, 0x000000a8, - 0x000000ac, 0x000000b0, 0x000000b4, 0x000000b8, 0x000000bc, 0x000000c0, - 0x000000c4, 0x000000c8, 0x000000cc, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff -}; - - -static const uint32_t d1[256] = { - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000e003, 0x01ffffff, 0x01ffffff, - 0x00004003, 0x00005003, 0x00006003, 0x00007003, 0x00008003, 0x00009003, - 0x0000a003, 0x0000b003, 0x0000c003, 0x0000d003, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, - 0x00001000, 0x00002000, 0x00003000, 0x00004000, 0x00005000, 0x00006000, - 0x00007000, 0x00008000, 0x00009000, 0x0000a000, 0x0000b000, 0x0000c000, - 0x0000d000, 0x0000e000, 0x0000f000, 0x00000001, 0x00001001, 0x00002001, - 0x00003001, 0x00004001, 0x00005001, 0x00006001, 0x00007001, 0x00008001, - 0x00009001, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000f003, - 0x01ffffff, 0x0000a001, 0x0000b001, 0x0000c001, 0x0000d001, 0x0000e001, - 0x0000f001, 0x00000002, 0x00001002, 0x00002002, 0x00003002, 0x00004002, - 0x00005002, 0x00006002, 0x00007002, 0x00008002, 0x00009002, 0x0000a002, - 0x0000b002, 0x0000c002, 0x0000d002, 0x0000e002, 0x0000f002, 0x00000003, - 0x00001003, 0x00002003, 0x00003003, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff -}; - - -static const uint32_t d2[256] = { - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00800f00, 0x01ffffff, 0x01ffffff, - 0x00000d00, 0x00400d00, 0x00800d00, 0x00c00d00, 0x00000e00, 0x00400e00, - 0x00800e00, 0x00c00e00, 0x00000f00, 0x00400f00, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, - 0x00400000, 0x00800000, 0x00c00000, 0x00000100, 0x00400100, 0x00800100, - 0x00c00100, 0x00000200, 0x00400200, 0x00800200, 0x00c00200, 0x00000300, - 0x00400300, 0x00800300, 0x00c00300, 0x00000400, 0x00400400, 0x00800400, - 0x00c00400, 0x00000500, 0x00400500, 0x00800500, 0x00c00500, 0x00000600, - 0x00400600, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00c00f00, - 0x01ffffff, 0x00800600, 0x00c00600, 0x00000700, 0x00400700, 0x00800700, - 0x00c00700, 0x00000800, 0x00400800, 0x00800800, 0x00c00800, 0x00000900, - 0x00400900, 0x00800900, 0x00c00900, 0x00000a00, 0x00400a00, 0x00800a00, - 0x00c00a00, 0x00000b00, 0x00400b00, 0x00800b00, 0x00c00b00, 0x00000c00, - 0x00400c00, 0x00800c00, 0x00c00c00, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff -}; - - -static const uint32_t d3[256] = { - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x003e0000, 0x01ffffff, 0x01ffffff, - 0x00340000, 0x00350000, 0x00360000, 0x00370000, 0x00380000, 0x00390000, - 0x003a0000, 0x003b0000, 0x003c0000, 0x003d0000, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, - 0x00010000, 0x00020000, 0x00030000, 0x00040000, 0x00050000, 0x00060000, - 0x00070000, 0x00080000, 0x00090000, 0x000a0000, 0x000b0000, 0x000c0000, - 0x000d0000, 0x000e0000, 0x000f0000, 0x00100000, 0x00110000, 0x00120000, - 0x00130000, 0x00140000, 0x00150000, 0x00160000, 0x00170000, 0x00180000, - 0x00190000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x003f0000, - 0x01ffffff, 0x001a0000, 0x001b0000, 0x001c0000, 0x001d0000, 0x001e0000, - 0x001f0000, 0x00200000, 0x00210000, 0x00220000, 0x00230000, 0x00240000, - 0x00250000, 0x00260000, 0x00270000, 0x00280000, 0x00290000, 0x002a0000, - 0x002b0000, 0x002c0000, 0x002d0000, 0x002e0000, 0x002f0000, 0x00300000, - 0x00310000, 0x00320000, 0x00330000, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, - 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff -}; - - -#endif diff --git a/third_party/stringencoders/src/modp_stdint.h b/third_party/stringencoders/src/modp_stdint.h deleted file mode 100644 index bd9dea37..00000000 --- a/third_party/stringencoders/src/modp_stdint.h +++ /dev/null @@ -1,43 +0,0 @@ -/* vi: set ft=c expandtab shiftwidth=4 tabstop=4: */ -#ifndef MODP_STDINT_H_ -#define MODP_STDINT_H_ - -/** - * \file modp_stdint.h - * \brief An attempt to make stringencoders compile under windows - * - * This attempts to define various integral types that are normally - * defined in stdint.h and stdbool.h which oddly don't exit on - * windows. - * - * Please file bugs or patches if it doesn't work! - */ - -#include - -#ifndef _WIN32 -#include -#include -#else -/* win64 is llp64 so these are the same for 32/64bit - so no check for _WIN64 is required. - */ -typedef unsigned char uint8_t; -typedef signed char int8_t; -typedef unsigned short uint16_t; -typedef signed short int16_t; -typedef unsigned int uint32_t; -typedef signed int int32_t; -typedef unsigned __int64 uint64_t; -typedef signed __int64 int64_t; - -/* windows doesn't do C99 and stdbool */ - -#ifndef __cplusplus -typedef unsigned char bool; -#define true 1 -#define false 0 -#endif - -#endif /* _WIN32 */ -#endif /* MODP_STDINT_H_ */