/src/serenity/Userland/Libraries/LibCrypto/Hash/MD5.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2020, Ali Mohammad Pur <mpfard@serenityos.org> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #pragma once |
8 | | |
9 | | #include <AK/Types.h> |
10 | | #include <LibCrypto/Hash/HashFunction.h> |
11 | | |
12 | | #ifndef KERNEL |
13 | | # include <AK/ByteString.h> |
14 | | #endif |
15 | | |
16 | | namespace Crypto::Hash { |
17 | | |
18 | | namespace MD5Constants { |
19 | | |
20 | | constexpr u32 init_A = 0x67452301; |
21 | | constexpr u32 init_B = 0xefcdab89; |
22 | | constexpr u32 init_C = 0x98badcfe; |
23 | | constexpr u32 init_D = 0x10325476; |
24 | | constexpr u32 S11 = 7; |
25 | | constexpr u32 S12 = 12; |
26 | | constexpr u32 S13 = 17; |
27 | | constexpr u32 S14 = 22; |
28 | | constexpr u32 S21 = 5; |
29 | | constexpr u32 S22 = 9; |
30 | | constexpr u32 S23 = 14; |
31 | | constexpr u32 S24 = 20; |
32 | | constexpr u32 S31 = 4; |
33 | | constexpr u32 S32 = 11; |
34 | | constexpr u32 S33 = 16; |
35 | | constexpr u32 S34 = 23; |
36 | | constexpr u32 S41 = 6; |
37 | | constexpr u32 S42 = 10; |
38 | | constexpr u32 S43 = 15; |
39 | | constexpr u32 S44 = 21; |
40 | | constexpr u8 PADDING[] = { |
41 | | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
42 | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
43 | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
44 | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
45 | | 0 |
46 | | }; |
47 | | |
48 | | } |
49 | | |
50 | | class MD5 final : public HashFunction<512, 128> { |
51 | | public: |
52 | | using HashFunction::update; |
53 | | |
54 | | virtual void update(u8 const*, size_t) override; |
55 | | virtual DigestType digest() override; |
56 | | virtual DigestType peek() override; |
57 | | |
58 | | #ifndef KERNEL |
59 | | virtual ByteString class_name() const override |
60 | 0 | { |
61 | 0 | return "MD5"; |
62 | 0 | } |
63 | | #endif |
64 | | |
65 | | static DigestType hash(u8 const* data, size_t length) |
66 | 126 | { |
67 | 126 | MD5 md5; |
68 | 126 | md5.update(data, length); |
69 | 126 | return md5.digest(); |
70 | 126 | } |
71 | | |
72 | 0 | static DigestType hash(ByteBuffer const& buffer) { return hash(buffer.data(), buffer.size()); } |
73 | 0 | static DigestType hash(StringView buffer) { return hash((u8 const*)buffer.characters_without_null_termination(), buffer.length()); } |
74 | | virtual void reset() override |
75 | 536 | { |
76 | 536 | m_A = MD5Constants::init_A; |
77 | 536 | m_B = MD5Constants::init_B; |
78 | 536 | m_C = MD5Constants::init_C; |
79 | 536 | m_D = MD5Constants::init_D; |
80 | | |
81 | 536 | m_count[0] = 0; |
82 | 536 | m_count[1] = 0; |
83 | | |
84 | 536 | __builtin_memset(m_data_buffer, 0, sizeof(m_data_buffer)); |
85 | 536 | } |
86 | | |
87 | | private: |
88 | | inline void transform(u8 const*); |
89 | | |
90 | | static void encode(u32 const* from, u8* to, size_t length); |
91 | | static void decode(u8 const* from, u32* to, size_t length); |
92 | | |
93 | | u32 m_A { MD5Constants::init_A }, m_B { MD5Constants::init_B }, m_C { MD5Constants::init_C }, m_D { MD5Constants::init_D }; |
94 | | u32 m_count[2] { 0, 0 }; |
95 | | |
96 | | u8 m_data_buffer[64] {}; |
97 | | }; |
98 | | |
99 | | } |