|
| 1 | +//========= Copyright Valve LLC, All rights reserved. ========================= |
| 2 | + |
| 3 | +#ifndef CRYPTO_25519_H |
| 4 | +#define CRYPTO_25519_H |
| 5 | + |
| 6 | +#include "crypto_constants.h" |
| 7 | +#include "keypair.h" |
| 8 | + |
| 9 | +class CEC25519KeyBase : public CCryptoKeyBase_RawBuffer |
| 10 | +{ |
| 11 | +public: |
| 12 | + virtual ~CEC25519KeyBase(); |
| 13 | + virtual bool IsValid() const override; |
| 14 | + virtual uint32 GetRawData( void *pData ) const override; |
| 15 | + virtual void Wipe() override; |
| 16 | + |
| 17 | + void *evp_pkey() const { return m_evp_pkey; } |
| 18 | +protected: |
| 19 | + virtual bool SetRawData( const void *pData, size_t cbData ) override; |
| 20 | + inline CEC25519KeyBase( ECryptoKeyType keyType ) : CCryptoKeyBase_RawBuffer( keyType ), m_evp_pkey(nullptr) {} |
| 21 | + |
| 22 | + // Actually EVP_PKEY*, but we don't want to include OpenSSL headers here, |
| 23 | + // especially since we might not actually be using OpenSSL for this at all! |
| 24 | + void *m_evp_pkey; |
| 25 | +}; |
| 26 | + |
| 27 | +//----------------------------------------------------------------------------- |
| 28 | +// Purpose: Common base for x25519 and ed25519 public keys on the 25519 curve |
| 29 | +// The raw data is 32 bytes |
| 30 | +//----------------------------------------------------------------------------- |
| 31 | +class CEC25519PublicKeyBase : public CEC25519KeyBase |
| 32 | +{ |
| 33 | +public: |
| 34 | + virtual ~CEC25519PublicKeyBase(); |
| 35 | +protected: |
| 36 | + CEC25519PublicKeyBase( ECryptoKeyType eType ) : CEC25519KeyBase( eType ) { } |
| 37 | +}; |
| 38 | + |
| 39 | +//----------------------------------------------------------------------------- |
| 40 | +// Purpose: Common base for x25519 and ed25519 private keys on the 25519 curve |
| 41 | +// The raw data is 32 bytes. |
| 42 | +// NOTE: An old version also stored the public key in the raw data. |
| 43 | +// We don't do that anymore.) If you want that, get the public |
| 44 | +// key data specifically |
| 45 | +//----------------------------------------------------------------------------- |
| 46 | +class CEC25519PrivateKeyBase : public CEC25519KeyBase |
| 47 | +{ |
| 48 | +public: |
| 49 | + virtual ~CEC25519PrivateKeyBase(); |
| 50 | + virtual void Wipe() override; |
| 51 | + bool GetPublicKey( CEC25519PublicKeyBase *pPublicKey ) const; |
| 52 | + bool MatchesPublicKey( const CEC25519PublicKeyBase &pPublicKey ) const; |
| 53 | + |
| 54 | + const uint8 *GetPublicKeyRawData() const { return m_publicKey; } |
| 55 | + |
| 56 | +protected: |
| 57 | + CEC25519PrivateKeyBase( ECryptoKeyType eType ) : CEC25519KeyBase( eType ) { } |
| 58 | + |
| 59 | + // We keep a copy of the public key cached. |
| 60 | + // It is not considered part of the raw key data, |
| 61 | + // as was previously the case.) |
| 62 | + uint8 m_publicKey[32]; |
| 63 | + |
| 64 | + bool CachePublicKey(); |
| 65 | + virtual bool SetRawData( const void *pData, size_t cbData ) override; |
| 66 | +}; |
| 67 | + |
| 68 | + |
| 69 | +//----------------------------------------------------------------------------- |
| 70 | +// Purpose: Encapsulates an elliptic-curve signature private key (x25519) |
| 71 | +//----------------------------------------------------------------------------- |
| 72 | +class CECKeyExchangePrivateKey : public CEC25519PrivateKeyBase |
| 73 | +{ |
| 74 | +public: |
| 75 | + CECKeyExchangePrivateKey() : CEC25519PrivateKeyBase( k_ECryptoKeyTypeKeyExchangePrivate ) { } |
| 76 | + virtual ~CECKeyExchangePrivateKey(); |
| 77 | +}; |
| 78 | + |
| 79 | + |
| 80 | +//----------------------------------------------------------------------------- |
| 81 | +// Purpose: Encapsulates an elliptic-curve key-exchange public key (curve25519) |
| 82 | +// Internally, this is stored as a 32-byte binary data blob |
| 83 | +//----------------------------------------------------------------------------- |
| 84 | +class CECKeyExchangePublicKey : public CEC25519PublicKeyBase |
| 85 | +{ |
| 86 | +public: |
| 87 | + CECKeyExchangePublicKey() : CEC25519PublicKeyBase( k_ECryptoKeyTypeKeyExchangePublic ) { } |
| 88 | + virtual ~CECKeyExchangePublicKey(); |
| 89 | +}; |
| 90 | + |
| 91 | + |
| 92 | +//----------------------------------------------------------------------------- |
| 93 | +// Purpose: Encapsulates an elliptic-curve signature private key (ed25519) |
| 94 | +// Internally, this is stored as a 64-byte (public, private) pair |
| 95 | +//----------------------------------------------------------------------------- |
| 96 | +class CECSigningPrivateKey : public CEC25519PrivateKeyBase |
| 97 | +{ |
| 98 | +public: |
| 99 | + CECSigningPrivateKey() : CEC25519PrivateKeyBase( k_ECryptoKeyTypeSigningPrivate ) { } |
| 100 | + |
| 101 | + // Load from PEM |
| 102 | + virtual bool LoadFromAndWipeBuffer( void *pBuffer, size_t cBytes ) override; |
| 103 | + |
| 104 | + // Purpose: Get key in PEM text format |
| 105 | + // Input: pchPEMData - Pointer to string buffer to store output in (or NULL to just calculate required size) |
| 106 | + // cubPEMData - Size of pchPEMData buffer |
| 107 | + // pcubPEMData - Pointer to number of bytes written to pchPEMData (including terminating nul), or |
| 108 | + // required size of pchPEMData if it is NULL or not big enough. |
| 109 | + bool GetAsPEM( char *pchPEMData, uint32 cubPEMData, uint32 *pcubPEMData ) const; |
| 110 | + |
| 111 | + // Parses OpenSSH PEM block. |
| 112 | + // WARNING: DOES NOT WIPE INPUT. |
| 113 | + bool ParsePEM( const char *pBuffer, size_t cBytes ); |
| 114 | + |
| 115 | + // Generate an ed25519 public-key signature |
| 116 | + void GenerateSignature( const void *pData, size_t cbData, CryptoSignature_t *pSignatureOut ) const; |
| 117 | +}; |
| 118 | + |
| 119 | +//----------------------------------------------------------------------------- |
| 120 | +// Purpose: Encapsulates an elliptic-curve signature public key (x25519) |
| 121 | +// Internally, this is stored as a 32-byte binary data blob |
| 122 | +//----------------------------------------------------------------------------- |
| 123 | +class CECSigningPublicKey : public CEC25519PublicKeyBase |
| 124 | +{ |
| 125 | +public: |
| 126 | + CECSigningPublicKey() : CEC25519PublicKeyBase( k_ECryptoKeyTypeSigningPublic ) { } |
| 127 | + |
| 128 | + virtual bool LoadFromAndWipeBuffer( void *pBuffer, size_t cBytes ) override; |
| 129 | + |
| 130 | + bool GetAsOpenSSHAuthorizedKeys( char *pchData, uint32 cubData, uint32 *pcubData, const char *pszComment = "" ) const; |
| 131 | + bool SetFromOpenSSHAuthorizedKeys( const char *pchData, size_t cbData ); |
| 132 | + |
| 133 | + bool VerifySignature( const void *pData, size_t cbData, const CryptoSignature_t &signature ) const; |
| 134 | +}; |
| 135 | + |
| 136 | +#ifdef VALVE_CRYPTO_ENABLE_25519 |
| 137 | + |
| 138 | +namespace CCrypto |
| 139 | +{ |
| 140 | + |
| 141 | + // |
| 142 | + // Secure key exchange (curve25519 elliptic-curve Diffie-Hellman key exchange) |
| 143 | + // |
| 144 | + |
| 145 | + // Generate a X25519 key pair for Diffie-Hellman secure key exchange. |
| 146 | + // pPublicKey can be null. (Since the private key also has a copy of the public key.) |
| 147 | + void GenerateKeyExchangeKeyPair( CECKeyExchangePublicKey *pPublicKey, CECKeyExchangePrivateKey *pPrivateKey ); |
| 148 | + |
| 149 | + // Do Diffie-Hellman secure key exchange. |
| 150 | + // NOTE: this actually returns the SHA256 of the raw DH result. I don't know why. |
| 151 | + bool PerformKeyExchange( const CECKeyExchangePrivateKey &localPrivateKey, const CECKeyExchangePublicKey &remotePublicKey, SHA256Digest_t *pSharedSecretOut ); |
| 152 | + |
| 153 | + // |
| 154 | + // Signing and verification (ed25519 elliptic-curve signature scheme) |
| 155 | + // |
| 156 | + |
| 157 | + // Generate an ed25519 key pair for public-key signature generation |
| 158 | + void GenerateSigningKeyPair( CECSigningPublicKey *pPublicKey, CECSigningPrivateKey *pPrivateKey ); |
| 159 | + |
| 160 | + // Legacy compatibility - use the key methods |
| 161 | + inline void GenerateSignature( const void *pData, size_t cbData, const CECSigningPrivateKey &privateKey, CryptoSignature_t *pSignatureOut ) { privateKey.GenerateSignature( pData, cbData, pSignatureOut ); } |
| 162 | + inline bool VerifySignature( const void *pData, size_t cbData, const CECSigningPublicKey &publicKey, const CryptoSignature_t &signature ) { return publicKey.VerifySignature( pData, cbData, signature ); } |
| 163 | +}; |
| 164 | + |
| 165 | +#endif // #ifdef VALVE_CRYPTO_ENABLE_25519 |
| 166 | + |
| 167 | +#endif // CRYPTO_H |
0 commit comments