Coverage Report

Created: 2025-12-18 07:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/Userland/Libraries/LibCrypto/Cipher/Cipher.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2020, Ali Mohammad Pur <mpfard@serenityos.org>
3
 * Copyright (c) 2022, the SerenityOS developers.
4
 *
5
 * SPDX-License-Identifier: BSD-2-Clause
6
 */
7
8
#pragma once
9
10
#include <AK/Optional.h>
11
#include <AK/Span.h>
12
#include <AK/Types.h>
13
14
namespace Crypto::Cipher {
15
16
enum class Intent {
17
    Encryption,
18
    Decryption,
19
};
20
21
enum class PaddingMode {
22
    CMS,     // RFC 1423
23
    RFC5246, // very similar to CMS, but filled with |length - 1|, instead of |length|
24
    Null,
25
    // FIXME: We do not implement these yet
26
    Bit,
27
    Random,
28
    Space,
29
    ZeroLength,
30
};
31
32
template<typename B, typename T>
33
class Cipher;
34
35
struct CipherBlock {
36
public:
37
    explicit CipherBlock(PaddingMode mode)
38
0
        : m_padding_mode(mode)
39
0
    {
40
0
    }
41
42
    virtual ReadonlyBytes bytes() const = 0;
43
44
    virtual void overwrite(ReadonlyBytes) = 0;
45
0
    virtual void overwrite(u8 const* data, size_t size) { overwrite({ data, size }); }
46
47
    virtual void apply_initialization_vector(ReadonlyBytes ivec) = 0;
48
49
0
    PaddingMode padding_mode() const { return m_padding_mode; }
50
0
    void set_padding_mode(PaddingMode mode) { m_padding_mode = mode; }
51
52
    template<typename T>
53
    void put(size_t offset, T value)
54
0
    {
55
0
        VERIFY(offset + sizeof(T) <= bytes().size());
56
0
        auto* ptr = bytes().offset_pointer(offset);
57
0
        auto index { 0 };
58
59
0
        VERIFY(sizeof(T) <= 4);
60
61
        if constexpr (sizeof(T) > 3)
62
0
            ptr[index++] = (u8)(value >> 24);
63
64
        if constexpr (sizeof(T) > 2)
65
0
            ptr[index++] = (u8)(value >> 16);
66
67
        if constexpr (sizeof(T) > 1)
68
0
            ptr[index++] = (u8)(value >> 8);
69
70
0
        ptr[index] = (u8)value;
71
0
    }
72
73
protected:
74
0
    virtual ~CipherBlock() = default;
75
76
private:
77
    virtual Bytes bytes() = 0;
78
    PaddingMode m_padding_mode;
79
};
80
81
struct CipherKey {
82
    virtual ReadonlyBytes bytes() const = 0;
83
0
    static bool is_valid_key_size(size_t) { return false; }
84
85
0
    virtual ~CipherKey() = default;
86
87
protected:
88
    virtual void expand_encrypt_key(ReadonlyBytes user_key, size_t bits) = 0;
89
    virtual void expand_decrypt_key(ReadonlyBytes user_key, size_t bits) = 0;
90
    size_t bits { 0 };
91
};
92
93
template<typename KeyT = CipherKey, typename BlockT = CipherBlock>
94
class Cipher {
95
public:
96
    using KeyType = KeyT;
97
    using BlockType = BlockT;
98
99
    explicit Cipher(PaddingMode mode)
100
0
        : m_padding_mode(mode)
101
0
    {
102
0
    }
103
104
    virtual KeyType const& key() const = 0;
105
    virtual KeyType& key() = 0;
106
107
0
    constexpr static size_t block_size() { return BlockType::block_size(); }
108
109
0
    PaddingMode padding_mode() const { return m_padding_mode; }
110
111
    virtual void encrypt_block(BlockType const& in, BlockType& out) = 0;
112
    virtual void decrypt_block(BlockType const& in, BlockType& out) = 0;
113
114
#ifndef KERNEL
115
    virtual ByteString class_name() const = 0;
116
#endif
117
118
protected:
119
0
    virtual ~Cipher() = default;
120
121
private:
122
    PaddingMode m_padding_mode;
123
};
124
}