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 0a389092..941a5a38 100644 Binary files a/Widevine_CE_CDM_IntegrationGuide_v3.3.x.pdf and b/Widevine_CE_CDM_IntegrationGuide_v3.4.x.pdf differ 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_ */