5 #include <decaf/eddsa.hxx>
6 #include <decaf/spongerng.hxx>
8 #include "dnssecinfra.hh"
10 using namespace decaf
;
12 class DecafED25519DNSCryptoKeyEngine
: public DNSCryptoKeyEngine
15 explicit DecafED25519DNSCryptoKeyEngine(unsigned int algo
) : DNSCryptoKeyEngine(algo
)
19 string
getName() const override
{ return "Decaf ED25519"; }
20 void create(unsigned int bits
) override
;
21 storvector_t
convertToISCVector() const override
;
22 std::string
getPubKeyHash() const override
;
23 std::string
sign(const std::string
& msg
) const override
;
24 bool verify(const std::string
& msg
, const std::string
& signature
) const override
;
25 std::string
getPublicKeyString() const override
;
26 int getBits() const override
;
27 void fromISCMap(DNSKEYRecordContent
& drc
, std::map
<std::string
, std::string
>& stormap
) override
;
28 void fromPublicKeyString(const std::string
& content
) override
;
30 static std::unique_ptr
<DNSCryptoKeyEngine
> maker(unsigned int algorithm
)
32 return make_unique
<DecafED25519DNSCryptoKeyEngine
>(algorithm
);
36 unsigned char d_pubkey
[DECAF_EDDSA_25519_PUBLIC_BYTES
];
37 unsigned char d_seckey
[DECAF_EDDSA_25519_PRIVATE_BYTES
];
40 void DecafED25519DNSCryptoKeyEngine::create(unsigned int bits
)
42 if(bits
!= (unsigned int)getBits()) {
43 throw runtime_error("Unsupported key length of "+std::to_string(bits
)+" bits requested, DecafED25519 class");
46 SpongeRng
rng("/dev/urandom");
48 typename EdDSA
<IsoEd25519
>::PrivateKey
priv(rng
);
49 typename EdDSA
<IsoEd25519
>::PublicKey
pub(priv
);
51 priv
.serialize_into(d_seckey
);
52 pub
.serialize_into(d_pubkey
);
55 int DecafED25519DNSCryptoKeyEngine::getBits() const
57 return DECAF_EDDSA_25519_PRIVATE_BYTES
<< 3;
60 DNSCryptoKeyEngine::storvector_t
DecafED25519DNSCryptoKeyEngine::convertToISCVector() const
63 Private-key-format: v1.2
64 Algorithm: 15 (ED25519)
65 PrivateKey: ODIyNjAzODQ2MjgwODAxMjI2NDUxOTAyMDQxNDIyNjI=
68 auto storvector
= storvector_t
{
69 {"Algorithm", "15 (ED25519)"},
70 {"PrivateKey", string((char*)d_seckey
, DECAF_EDDSA_25519_PRIVATE_BYTES
)},
76 void DecafED25519DNSCryptoKeyEngine::fromISCMap(DNSKEYRecordContent
& drc
, std::map
<std::string
, std::string
>& stormap
)
79 Private-key-format: v1.2
80 Algorithm: 15 (ED25519)
81 PrivateKey: ODIyNjAzODQ2MjgwODAxMjI2NDUxOTAyMDQxNDIyNjI=
84 pdns::checked_stoi_into(drc
.d_algorithm
, stormap
["algorithm"]);
85 string privateKey
= stormap
["privatekey"];
87 if (privateKey
.length() != DECAF_EDDSA_25519_PRIVATE_BYTES
)
88 throw runtime_error("Private key size mismatch in ISCMap, DecafED25519 class");
90 typename EdDSA
<IsoEd25519
>::PrivateKey
priv(Block((const unsigned char*)privateKey
.c_str(), DECAF_EDDSA_25519_PRIVATE_BYTES
));
91 typename EdDSA
<IsoEd25519
>::PublicKey
pub(priv
);
93 priv
.serialize_into(d_seckey
);
94 pub
.serialize_into(d_pubkey
);
97 std::string
DecafED25519DNSCryptoKeyEngine::getPubKeyHash() const
99 return this->getPublicKeyString();
102 std::string
DecafED25519DNSCryptoKeyEngine::getPublicKeyString() const
104 return string((char*)d_pubkey
, DECAF_EDDSA_25519_PUBLIC_BYTES
);
107 void DecafED25519DNSCryptoKeyEngine::fromPublicKeyString(const std::string
& input
)
109 if (input
.length() != DECAF_EDDSA_25519_PUBLIC_BYTES
)
110 throw runtime_error("Public key size mismatch, DecafED25519 class");
112 memcpy(d_pubkey
, input
.c_str(), DECAF_EDDSA_25519_PUBLIC_BYTES
);
115 std::string
DecafED25519DNSCryptoKeyEngine::sign(const std::string
& msg
) const
117 typename EdDSA
<IsoEd25519
>::PrivateKey
priv(Block(d_seckey
, DECAF_EDDSA_25519_PRIVATE_BYTES
));
119 SecureBuffer
message(msg
.begin(), msg
.end());
121 SecureBuffer sig
= priv
.sign(message
);
123 return string(sig
.begin(), sig
.end());
126 bool DecafED25519DNSCryptoKeyEngine::verify(const std::string
& msg
, const std::string
& signature
) const
128 if (signature
.length() != DECAF_EDDSA_25519_SIGNATURE_BYTES
)
131 typename EdDSA
<IsoEd25519
>::PublicKey
pub(Block(d_pubkey
, DECAF_EDDSA_25519_PUBLIC_BYTES
));
133 SecureBuffer
sig(signature
.begin(), signature
.end());
134 SecureBuffer
message(msg
.begin(), msg
.end());
137 pub
.verify(sig
, message
);
138 } catch(const CryptoException
& e
) {
146 class DecafED448DNSCryptoKeyEngine
: public DNSCryptoKeyEngine
149 explicit DecafED448DNSCryptoKeyEngine(unsigned int algo
) : DNSCryptoKeyEngine(algo
)
153 string
getName() const override
{ return "Decaf ED448"; }
154 void create(unsigned int bits
) override
;
155 storvector_t
convertToISCVector() const override
;
156 std::string
getPubKeyHash() const override
;
157 std::string
sign(const std::string
& msg
) const override
;
158 bool verify(const std::string
& msg
, const std::string
& signature
) const override
;
159 std::string
getPublicKeyString() const override
;
160 int getBits() const override
;
161 void fromISCMap(DNSKEYRecordContent
& drc
, std::map
<std::string
, std::string
>& stormap
) override
;
162 void fromPublicKeyString(const std::string
& content
) override
;
163 void fromPEMString(DNSKEYRecordContent
& drc
, const std::string
& raw
) override
166 static std::unique_ptr
<DNSCryptoKeyEngine
> maker(unsigned int algorithm
)
168 return make_unique
<DecafED448DNSCryptoKeyEngine
>(algorithm
);
172 unsigned char d_pubkey
[DECAF_EDDSA_448_PUBLIC_BYTES
];
173 unsigned char d_seckey
[DECAF_EDDSA_448_PRIVATE_BYTES
];
176 void DecafED448DNSCryptoKeyEngine::create(unsigned int bits
)
178 if(bits
!= (unsigned int)getBits()) {
179 throw runtime_error("Unsupported key length of "+std::to_string(bits
)+" bits requested, DecafED448 class");
182 SpongeRng
rng("/dev/urandom");
184 typename EdDSA
<Ed448Goldilocks
>::PrivateKey
priv(rng
);
185 typename EdDSA
<Ed448Goldilocks
>::PublicKey
pub(priv
);
187 priv
.serialize_into(d_seckey
);
188 pub
.serialize_into(d_pubkey
);
191 int DecafED448DNSCryptoKeyEngine::getBits() const
193 return DECAF_EDDSA_448_PRIVATE_BYTES
<< 3;
196 DNSCryptoKeyEngine::storvector_t
DecafED448DNSCryptoKeyEngine::convertToISCVector() const
199 Private-key-format: v1.2
200 Algorithm: 16 (ED448)
201 PrivateKey: xZ+5Cgm463xugtkY5B0Jx6erFTXp13rYegst0qRtNsOYnaVpMx0Z/c5EiA9x8wWbDDct/U3FhYWA
204 auto storvector
= storvector_t
{
205 {"Algorithm", "16 (ED448)"},
206 {"PrivateKey", string((char*)d_seckey
, DECAF_EDDSA_448_PRIVATE_BYTES
)},
212 void DecafED448DNSCryptoKeyEngine::fromISCMap(DNSKEYRecordContent
& drc
, std::map
<std::string
, std::string
>& stormap
)
215 Private-key-format: v1.2
216 Algorithm: 16 (ED448)
217 PrivateKey: xZ+5Cgm463xugtkY5B0Jx6erFTXp13rYegst0qRtNsOYnaVpMx0Z/c5EiA9x8wWbDDct/U3FhYWA
220 pdns::checked_stoi_into(drc
.d_algorithm
, stormap
["algorithm"]);
221 string privateKey
= stormap
["privatekey"];
223 if (privateKey
.length() != DECAF_EDDSA_448_PRIVATE_BYTES
)
224 throw runtime_error("Private key size mismatch in ISCMap, DecafED448 class");
226 typename EdDSA
<Ed448Goldilocks
>::PrivateKey
priv(Block((const unsigned char*)privateKey
.c_str(), DECAF_EDDSA_448_PRIVATE_BYTES
));
227 typename EdDSA
<Ed448Goldilocks
>::PublicKey
pub(priv
);
229 priv
.serialize_into(d_seckey
);
230 pub
.serialize_into(d_pubkey
);
233 std::string
DecafED448DNSCryptoKeyEngine::getPubKeyHash() const
235 return this->getPublicKeyString();
238 std::string
DecafED448DNSCryptoKeyEngine::getPublicKeyString() const
240 return string((char*)d_pubkey
, DECAF_EDDSA_448_PUBLIC_BYTES
);
243 void DecafED448DNSCryptoKeyEngine::fromPublicKeyString(const std::string
& input
)
245 if (input
.length() != DECAF_EDDSA_448_PUBLIC_BYTES
)
246 throw runtime_error("Public key size mismatch, DecafED448 class");
248 memcpy(d_pubkey
, input
.c_str(), DECAF_EDDSA_448_PUBLIC_BYTES
);
251 std::string
DecafED448DNSCryptoKeyEngine::sign(const std::string
& msg
) const
253 typename EdDSA
<Ed448Goldilocks
>::PrivateKey
priv(Block(d_seckey
, DECAF_EDDSA_448_PRIVATE_BYTES
));
255 SecureBuffer
message(msg
.begin(), msg
.end());
257 SecureBuffer sig
= priv
.sign(message
);
259 return string(sig
.begin(), sig
.end());
262 bool DecafED448DNSCryptoKeyEngine::verify(const std::string
& msg
, const std::string
& signature
) const
264 if (signature
.length() != DECAF_EDDSA_448_SIGNATURE_BYTES
)
267 typename EdDSA
<Ed448Goldilocks
>::PublicKey
pub(Block(d_pubkey
, DECAF_EDDSA_448_PUBLIC_BYTES
));
269 SecureBuffer
sig(signature
.begin(), signature
.end());
270 SecureBuffer
message(msg
.begin(), msg
.end());
273 pub
.verify(sig
, message
);
274 } catch(const CryptoException
& e
) {
283 struct LoaderDecafStruct
287 DNSCryptoKeyEngine::report(15, &DecafED25519DNSCryptoKeyEngine::maker
, true);
288 DNSCryptoKeyEngine::report(16, &DecafED448DNSCryptoKeyEngine::maker
);