void Packet::armor(const void *key,bool encryptPayload) { unsigned char mangledKey[32]; unsigned char macKey[32]; unsigned char mac[16]; const unsigned int payloadLen = size() - ZT_PACKET_IDX_VERB; unsigned char *const payload = field(ZT_PACKET_IDX_VERB,payloadLen); // Set flag now, since it affects key mangle function setCipher(encryptPayload ? ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012 : ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE); _salsa20MangleKey((const unsigned char *)key,mangledKey); Salsa20 s20(mangledKey,256,field(ZT_PACKET_IDX_IV,8)/*,ZT_PROTO_SALSA20_ROUNDS*/); // MAC key is always the first 32 bytes of the Salsa20 key stream // This is the same construction DJB's NaCl library uses s20.encrypt12(ZERO_KEY,macKey,sizeof(macKey)); if (encryptPayload) s20.encrypt12(payload,payload,payloadLen); Poly1305::compute(mac,payload,payloadLen,macKey); memcpy(field(ZT_PACKET_IDX_MAC,8),mac,8); }
bool KeePass2Reader::readHeaderField() { QByteArray fieldIDArray = m_headerStream->read(1); if (fieldIDArray.size() != 1) { raiseError("Invalid header id size"); return false; } quint8 fieldID = fieldIDArray.at(0); bool ok; quint16 fieldLen = Endian::readUInt16(m_headerStream, KeePass2::BYTEORDER, &ok); if (!ok) { raiseError("Invalid header field length"); return false; } QByteArray fieldData; if (fieldLen != 0) { fieldData = m_headerStream->read(fieldLen); if (fieldData.size() != fieldLen) { raiseError("Invalid header data length"); return false; } } switch (fieldID) { case KeePass2::EndOfHeader: m_headerEnd = true; break; case KeePass2::CipherID: setCipher(fieldData); break; case KeePass2::CompressionFlags: setCompressionFlags(fieldData); break; case KeePass2::MasterSeed: setMasterSeed(fieldData); break; case KeePass2::TransformSeed: setTransformSeed(fieldData); break; case KeePass2::TransformRounds: setTansformRounds(fieldData); break; case KeePass2::EncryptionIV: setEncryptionIV(fieldData); break; case KeePass2::ProtectedStreamKey: setProtectedStreamKey(fieldData); break; case KeePass2::StreamStartBytes: setStreamStartBytes(fieldData); break; case KeePass2::InnerRandomStreamID: setInnerRandomStreamID(fieldData); break; default: qWarning("Unknown header field read: id=%d", fieldID); break; } return !m_headerEnd; }