/*! * make a keyed-hash from a key using the HMAC-sha256 and a challenge * * \param key The key to make a digest for * \param challenge Some data mixin - identify the specific digest * \return a base64 encoded digest */ inline std::string compute_wcs( const std::string & key, const std::string & challenge ) { unsigned int len = 32; unsigned char hash[32]; #if (OPENSSL_VERSION_NUMBER < 0x10100000L) HMAC_CTX hmac; HMAC_CTX_init(&hmac); HMAC_Init_ex(&hmac, key.data(), key.length(), EVP_sha256(), NULL); HMAC_Update(&hmac, (unsigned char*) challenge.data(), challenge.length()); HMAC_Final(&hmac, hash, &len); HMAC_CTX_cleanup(&hmac); #else HMAC_CTX *hmac = HMAC_CTX_new(); if (!hmac) return ""; HMAC_Init_ex(hmac, key.data(), key.length(), EVP_sha256(), NULL); HMAC_Update(hmac, ( unsigned char* ) challenge.data(), challenge.length()); HMAC_Final(hmac, hash, &len); HMAC_CTX_free(hmac); #endif std::string str_out; str_out.assign( ( char * ) &hash , 32 ); return base_64_encode( str_out ); }
bool encode_request(const uint8_t *req, uint32_t req_len, uint8_t *out_buf, uint32_t *out_len) { uint32_t encoded_header_size = static_cast<uint32_t>(2*PROVISION_REQUEST_HEADER_SIZE); if(*out_len<encoded_header_size) return false; if(req_len<PROVISION_REQUEST_HEADER_SIZE) return false; if(!byte_array_to_hex_string(req, PROVISION_REQUEST_HEADER_SIZE, out_buf, encoded_header_size)) return false; uint32_t left_size = *out_len - encoded_header_size; if(req_len != GET_SIZE_FROM_PROVISION_REQUEST(req)) return false;//error in input message if(!base_64_encode(req+PROVISION_REQUEST_HEADER_SIZE, GET_BODY_SIZE_FROM_PROVISION_REQUEST(req), out_buf + encoded_header_size, &left_size)) return false; *out_len = left_size + encoded_header_size; return true; }
/*! * create a derived key from a password/secret * * \param passwd A secret string to make a derived key for * \param salt A random salt added to the key * \param iterations A number of intertions used to create the derived key * \param keylen The length of the derived key returned. * \return a PBKDF2-sha256 derived key */ inline std::string derive_key( const std::string & passwd, const std::string & salt, int iterations, int keylen ) { int passwdLen = passwd.size(); const char * pwd = passwd.c_str(); int saltLen = salt.size(); unsigned char * salt_value = (unsigned char * ) salt.c_str(); std::string str_out; str_out.resize( keylen ); unsigned char * out = (unsigned char *) str_out.c_str(); int result = PKCS5_PBKDF2_HMAC( pwd, passwdLen, salt_value, saltLen, iterations, EVP_sha256(), keylen, out); if ( result != 0 ) { return base_64_encode( str_out ); } else { throw derived_key_error(); } }