/* * This code is derived from (original license follows): * * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. * MD5 Message-Digest Algorithm (RFC 1321). * * Homepage: * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 * * Author: * Alexander Peslyak, better known as Solar Designer <solar at openwall.com> * * This software was written by Alexander Peslyak in 2001. No copyright is * claimed, and the software is hereby placed in the public domain. * In case this attempt to disclaim copyright and place the software in the * public domain is deemed null and void, then the software is * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the * general public under the following terms: * * Redistribution and use in source and binary forms, with or without * modification, are permitted. * * There's ABSOLUTELY NO WARRANTY, express or implied. * * (This is a heavily cut-down "BSD license".) * * This differs from Colin Plumb's older public domain implementation in that * no exactly 32-bit integer data type is required (any 32-bit or wider * unsigned integer data type will do), there's no compile-time endianness * configuration, and the function prototypes match OpenSSL's. No code from * Colin Plumb's implementation has been reused; this comment merely compares * the properties of the two independent implementations. * * The primary goals of this implementation are portability and ease of use. * It is meant to be fast, but not as fast as possible. Some known * optimizations are not included to reduce source code size and avoid * compile-time configuration. */ #include "llvm/Support/MD5.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Endian.h" #include <array> #include <cstdint> #include <cstring> // The basic MD5 functions. // F and G are optimized compared to their RFC 1321 definitions for // architectures that lack an AND-NOT instruction, just like in Colin Plumb's // implementation. #define F(x, y, z) … #define G(x, y, z) … #define H(x, y, z) … #define I(x, y, z) … // The MD5 transformation for all four rounds. #define STEP(f, a, b, c, d, x, t, s) … // SET reads 4 input bytes in little-endian byte order and stores them // in a properly aligned word in host byte order. #define SET(n) … #define GET(n) … usingnamespacellvm; /// This processes one or more 64-byte data blocks, but does NOT update ///the bit counters. There are no alignment requirements. const uint8_t *MD5::body(ArrayRef<uint8_t> Data) { … } MD5::MD5() = default; /// Incrementally add the bytes in \p Data to the hash. void MD5::update(ArrayRef<uint8_t> Data) { … } /// Add the bytes in the StringRef \p Str to the hash. // Note that this isn't a string and so this won't include any trailing NULL // bytes. void MD5::update(StringRef Str) { … } /// Finish the hash and place the resulting hash into \p result. /// \param Result is assumed to be a minimum of 16-bytes in size. void MD5::final(MD5Result &Result) { … } MD5::MD5Result MD5::final() { … } MD5::MD5Result MD5::result() { … } SmallString<32> MD5::MD5Result::digest() const { … } void MD5::stringifyResult(MD5Result &Result, SmallVectorImpl<char> &Str) { … } MD5::MD5Result MD5::hash(ArrayRef<uint8_t> Data) { … }