// Test vectors from RFC 6070. (See file header, above.) bool PBKDF2_TEST() { MemBuf mDig(100); MemBuf mOut(100); CvtHex( "0c60c80f961f0e71f3a9b524af6012062fe037a6", mDig ); if (0 != memcmp( mDig, PBKDF2("password", "salt", 1, 20, mOut), 20 )) { return false; } CvtHex( "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957", mDig ); if (0 != memcmp( mDig, PBKDF2("password", "salt", 2, 20, mOut), 20 )) { return false; } CvtHex( "4b007901b765489abead49d926f721d065a429c1", mDig ); if (0 != memcmp( mDig, PBKDF2("password", "salt", 4096, 20, mOut), 20)) { return false; } // This one is rather time consuming. //CvtHex( "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984", mDig ); //if (0 != memcmp( mDig, PBKDF2("password", "salt", 16777216, 20, mOut), 20)) { return false; } CvtHex( "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038", mDig ); if (0 != memcmp( mDig, PBKDF2("passwordPASSWORDpassword", "saltSALTsaltSALTsaltSALTsaltSALTsalt", 4096, 25, mOut), 25)) { return false; } CvtHex( "56fa6aa75548099dcc37d7f03425e0c3", mDig ); BYTE text[] = { 'p', 'a', 's', 's', 0, 'w', 'o', 'r', 'd' } ; BYTE salt[] = { 's', 'a', 0, 'l', 't' } ; if (0 != memcmp( mDig, PBKDF2( MemBuf(text,NELEM(text)), MemBuf(salt,NELEM(salt)), 4096, 16, mOut), 16)) { return false; } return true; }
// ---------------------------------------------------------------------------- // Password-based key derivation algorithm. // - text : typically, a user-entered password or phrase // - salt : caller's "entropy" // - count : number of times to iterate the hashing loop. // - length: the desired number of bytes in the returned byte array // - out : memory buffer filled with the requested number of bytes // ---------------------------------------------------------------------------- BYTE *PBKDF2(PCBYTE text, int textlen, PCBYTE salt, int saltlen, int count, int length, BYTE *out) { // Loop until we've generated the requested number of bytes. UINT more = length; for (int i=1; 0<more; i++) { // Where the magic happens. MemBuf outF; F( MemBuf( text, (UINT)textlen ), MemBuf( salt, (UINT)saltlen), count, i, outF ); // Append as many bytes of hash as needed to the key buffer. UINT nCopyCount = min(more, outF.size()); memcpy( &out[length-more], outF, nCopyCount); // Reduce the "more" counter by the number of bytes we just copied. more -= nCopyCount; } return out; }
/* \brief It accepts a XML (ascii) buffer and it parses it. This function is used when we have a char buffer containing an XML fragment, and we have to parse it. This function returns the list of PSML items (<section>) contained in the XML buffer. \param Buffer: pointer to a buffer that contains the XML fragment (in ascii). \param BufSize: number of valid bytes in the previous buffer; not NULL terminated buffers are supported as well. \return A pointer to the list of <section> nodes contained into the XML fragment if everything is fine, NULL otherwise. In case of error, the error message can be retrieved by the GetLastError() method. */ DOMNodeList *CPSMLReader::ParseMemBuf(char *Buffer, int BytesToParse) { DOMDocument *Document; XMLCh TempBuffer[NETPDL_MAX_STRING + 1]; MemBufInputSource MemBuf( (const XMLByte *) Buffer, BytesToParse, "", false); try { // Reset any other document previously created m_DOMParser->resetDocumentPool(); // Load the description in memory and get document root m_DOMParser->parse(MemBuf); Document= m_DOMParser->getDocument(); if ( (Document->getDocumentElement()) == NULL) { errorsnprintf(__FILE__, __FUNCTION__, __LINE__, m_errbuf, sizeof(m_errbuf), "Fatal error: cannot parse PSML file. Possible errors: " "wrong file location, or not well-formed XML file."); return NULL; } } catch (...) { errorsnprintf(__FILE__, __FUNCTION__, __LINE__, m_errbuf, sizeof(m_errbuf), "Unexpected exception during PSML buffer parsing."); return NULL; } if (Document == NULL) { errorsnprintf(__FILE__, __FUNCTION__, __LINE__, m_errbuf, sizeof(m_errbuf), "Unexpected exception during PSML buffer parsing."); return NULL; } XMLString::transcode(PSML_SECTION, TempBuffer, NETPDL_MAX_STRING); // After parsing the '<packet>' fragment, let's list the <section> contained into it return Document->getElementsByTagName(TempBuffer); }
/* \brief It accepts a XML (ascii) buffer and it parses it. This function is used when we have a char buffer containing an XML fragment, and we have to parse it. This function returns the list of PDML items (<section>) contained in the XML buffer. \param Buffer: pointer to a buffer that contains the XML fragment (in ascii). \param BytesToParse: number of valid bytes in the previous buffer; not NULL terminated buffers are supported as well. \return A pointer to the DOM document associated to the XML fragment if everything is fine, NULL otherwise. In case of error, the error message can be retrieved by the GetLastError() method. */ DOMDocument* CPDMLReader::ParseMemBuf(char *Buffer, int BytesToParse) { DOMDocument *Document; MemBufInputSource MemBuf( (const XMLByte *) Buffer, BytesToParse, "", false); try { // Reset any other document previously created m_DOMParser->resetDocumentPool(); // Load the description in memory and get document root m_DOMParser->parse(MemBuf); Document= m_DOMParser->getDocument(); if ( (Document->getDocumentElement()) == NULL) { errorsnprintf(__FILE__, __FUNCTION__, __LINE__, m_errbuf, sizeof(m_errbuf), "Fatal error: cannot parse PDML file. Possible errors: " "wrong file location, or not well-formed XML file."); return NULL; } } catch (...) { errorsnprintf(__FILE__, __FUNCTION__, __LINE__, m_errbuf, sizeof(m_errbuf), "Unexpected exception during PDML buffer parsing."); return NULL; } if (Document == NULL) { errorsnprintf(__FILE__, __FUNCTION__, __LINE__, m_errbuf, sizeof(m_errbuf), "Unexpected exception during PDML buffer parsing."); return NULL; } return Document; }