Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
DerivedKey.h
Go to the documentation of this file.
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Foundation_Cryptography_OpenSSL_DerivedKey_h_
5#define _Stroika_Foundation_Cryptography_OpenSSL_DerivedKey_h_ 1
6
7#include "Stroika/Foundation/StroikaPreComp.h"
8
9#include <compare>
10#include <optional>
11
13#include "Stroika/Foundation/Common/Common.h"
17#include "Stroika/Foundation/Memory/Common.h"
18
19/**
20 * \file
21 * \note VERY ROUGH PRELIMINARY DRAFT - NOT USEABLE YET
22 *
23 * TODO:
24 *
25 * \note \em Thread-Safety <a href="Thread-Safety.md#Automatically-Synchronized-Thread-Safety">Automatically-Synchronized-Thread-Safety</a>
26 *
27 */
28
29namespace Stroika::Foundation::Cryptography::Providers::OpenSSL {
30
31 using Characters::String;
32 using Memory::BLOB;
33
34#if qStroika_HasComponent_OpenSSL
35 /**
36 * \note <a href="Design-Overview.md#Comparisons">Comparisons</a>:
37 * o Standard Stroika Comparison support (operator<=>,operator==, etc);
38 * o (only for c++20 or later)
39 */
40 struct DerivedKey {
41 BLOB fKey;
42 BLOB fIV;
43
44 /*
45 * Gen key & IV. This requires the cipher algorithm (for the key / iv length) and the hash algorithm.
46 * nrounds is the number of times the we hash the material. More rounds are more secure but
47 * slower.
48 *
49 * For the ascii string, we treat the strings as an array of bytes (len bytes) long.
50 * For the String overload, we convert to UTF8 and treat as string (so "fred"_k and "fred" produce the same thing).
51 */
52 DerivedKey (const BLOB& key, const BLOB& iv);
53 DerivedKey (const pair<BLOB, BLOB>& keyAndIV);
54
55 public:
56 /**
57 */
58 nonvirtual auto operator<=> (const DerivedKey& rhs) const = default;
59
60 /**
61 */
62 nonvirtual String ToString () const;
63
64 /**
65 * These algorithms treat a password as just a BLOB - bunch of bytes. Typically, its an
66 * ascii string. But to this easier to work with in Stroika, we allow passing in different
67 * formats for the password, and provide standardized (within stroika) ways to produce the
68 * BLOB that is used as the crytopgraphic password. The only IMPORTANT thing about this algorithm
69 * is that it is repeatable, and that it maps ASCII characters to what everyone expects - those
70 * ascii bytes (thus the interoperability).
71 */
72 static BLOB NormalizePassword (const BLOB& passwd);
73 static BLOB NormalizePassword (const String& passwd);
74 };
75
76 /**
77 * WinCryptDeriveKey CAN be object sliced. Its a simple construction wrapper on a DerivedKey. WinCryptDeriveKey
78 * creates a Microsoft-Windows format derived key, compatible with the Windows WinCryptDeriveKey API.
79 *
80 * \note for new code - PKCS5_PBKDF2_HMAC is the preferred DerivedKey subclass to use
81 */
82 struct WinCryptDeriveKey : DerivedKey {
83 WinCryptDeriveKey (size_t keyLen, DigestAlgorithm digestAlgorithm, const BLOB& passwd);
84 enum Provider {
85 Base,
86 Enhanced,
87 Strong
88 };
89 WinCryptDeriveKey (Provider provider, CipherAlgorithm cipherAlgorithm, DigestAlgorithm digestAlgorithm, const BLOB& passwd);
90 };
91
92 /**
93 * EVP_BytesToKey CAN be object sliced. Its a simple construction wrapper on a DerivedKey. EVP_BytesToKey
94 * creates an OpenSSL-default-format, old-style crypto derived key.
95 *
96 * \note for new code - PKCS5_PBKDF2_HMAC is the preferred DerivedKey subclass to use
97 */
98 struct EVP_BytesToKey : DerivedKey {
99 /**
100 * In EVP_BytesToKey, the Salt must either by an 8-byte array or omitted.
101 *
102 * nRounds defaults to 1, because that's what is used in the openssl command-line tool (so it makes
103 * it easier to get the same results as it). But RFC 2898 suggests an iteration count of at least 1000.
104 */
105 template <typename PASSWORD_TYPE>
106 EVP_BytesToKey (CipherAlgorithm cipherAlgorithm, DigestAlgorithm digestAlgorithm, const PASSWORD_TYPE& passwd,
107 unsigned int nRounds = 1, const optional<BLOB>& salt = nullopt);
108 };
109 template <>
110 EVP_BytesToKey::EVP_BytesToKey (CipherAlgorithm cipherAlgorithm, DigestAlgorithm digestAlgorithm, const BLOB& passwd,
111 unsigned int nRounds, const optional<BLOB>& salt);
112
113 /**
114 * PKCS5_PBKDF2_HMAC CAN be object sliced. Its a simple construction wrapper on a DerivedKey. PKCS5_PBKDF1
115 * creates a PKCS5 PBKDF2 HMAC crypto derived key.
116 *
117 * RFC 2898 suggests an iteration count of at least 1000
118 *
119 * This function needs to know the keyLen and ivLen. You can pass those in explicitly, or pass in the cipher algorithm for the sole
120 * purpose of capturing those lengths.
121 *
122 * \note for new code - PKCS5_PBKDF2_HMAC is the preferred DerivedKey subclass to use
123 */
124 struct PKCS5_PBKDF2_HMAC : DerivedKey {
125 /**
126 * The passwd argument can be any type which is (unambiguously) convertible to String, string, or BLOB.
127 */
128 template <typename PASSWORD_TYPE>
129 PKCS5_PBKDF2_HMAC (size_t keyLen, size_t ivLen, DigestAlgorithm digestAlgorithm, const PASSWORD_TYPE& passwd,
130 unsigned int nRounds = 1000, const optional<BLOB>& salt = nullopt);
131 template <typename PASSWORD_TYPE, typename CIPHER_ALGORITHM_TYPE>
132 PKCS5_PBKDF2_HMAC (CIPHER_ALGORITHM_TYPE cipherAlgorithm, DigestAlgorithm digestAlgorithm, const PASSWORD_TYPE& passwd,
133 unsigned int nRounds = 1000, const optional<BLOB>& salt = nullopt);
134 };
135 template <>
136 PKCS5_PBKDF2_HMAC::PKCS5_PBKDF2_HMAC (size_t keyLen, size_t ivLen, DigestAlgorithm digestAlgorithm, const BLOB& passwd,
137 unsigned int nRounds, const optional<BLOB>& salt);
138
139 /**
140 * PKCS5_PBKDF2_HMAC_SHA1 be object sliced. Its a simple construction wrapper on a DerivedKey. PKCS5_PBKDF2_HMAC_SHA1
141 * creates a PKCS5_PBKDF2_HMAC_SHA1 crypto derived key.
142 *
143 * RFC 2898 suggests an iteration count of at least 1000.
144 *
145 * \note for new code - PKCS5_PBKDF2_HMAC (or PKCS5_PBKDF2_HMAC_SHA1) is the preferred DerivedKey subclass to use
146 */
147 struct PKCS5_PBKDF2_HMAC_SHA1 : PKCS5_PBKDF2_HMAC {
148 template <typename PASSWORD_TYPE>
149 PKCS5_PBKDF2_HMAC_SHA1 (size_t keyLen, size_t ivLen, const PASSWORD_TYPE& passwd, unsigned int nRounds = 1000,
150 const optional<BLOB>& salt = nullopt);
151 template <typename PASSWORD_TYPE, typename CIPHER_ALGORITHM_TYPE>
152 PKCS5_PBKDF2_HMAC_SHA1 (CIPHER_ALGORITHM_TYPE cipherAlgorithm, const PASSWORD_TYPE& passwd, unsigned int nRounds = 1000,
153 const optional<BLOB>& salt = nullopt);
154 };
155#endif
156}
157
158/*
159 ********************************************************************************
160 ***************************** Implementation Details ***************************
161 ********************************************************************************
162 */
163#include "DerivedKey.inl"
164
165#endif /*_Stroika_Foundation_Cryptography_OpenSSL_DerivedKey_h_*/
STRING_TYPE ToString(FLOAT_TYPE f, const ToStringOptions &options={})