logo.png
mORMot2 API Reference

mormot.crypt.openssl.pas unit

Purpose: Framework Core Cryptographic Process using OpenSSL
- this unit is a part of the Open Source Synopse mORMot framework 2, licensed under a MPL/GPL/LGPL three license - see LICENSE.md

1.1. Units used in the mormot.crypt.openssl unit

Unit NameDescription
mormot.core.baseFramework Core Shared Types and RTL-like Functions
mormot.core.buffersFramework Core Low-Level Memory Buffer Process
mormot.core.osFramework Core Low-Level Wrappers to the Operating-System API
mormot.core.rttiFramework Core Low-Level Cross-Compiler RTTI Definitions
mormot.core.textFramework Core Low-Level Text Processing
mormot.core.unicodeFramework Core Low-Level Unicode UTF-8 UTF-16 Ansi Conversion
mormot.crypt.coreFramework Core Cryptographic Process (Hashing and Cypher)
mormot.crypt.eccFramework Core High-Level Public-Key Elliptic-Curve Cryptography
mormot.crypt.ecc256r1Framework Core Public-Key Cryptography with secp256r1/NISTP-256 ECC Curves
mormot.crypt.jwtFramework Core JSON Web Tokens (JWT) Support
mormot.crypt.rsaFramework Core RSA Support
mormot.crypt.secureFramework Core Authentication and Security Features
mormot.lib.openssl11Low-level access to the OpenSSL 1.1 / 3.x Library

1.2. mormot.crypt.openssl class hierarchy

TOpenSslDigestAbstractTOpenSslHmacTOpenSslHashTObjectTAesOslTJwtAbstractOslTJwtRs512OslTJwtRs384OslTJwtRs256OslTJwtPs512OslTJwtPs384OslTJwtPs256OslTJwtEs512OslTJwtEs384OslTJwtEs256OslTJwtEs256KOslTJwtEddsaOslTJwtOpenSslTJwtAsymTEcc256r1VerifyAbstractTEcc256r1VerifyOslTCryptPublicKeyTCryptPublicKeyOpenSslTCryptPrivateKeyTCryptPrivateKeyOpenSslTCryptCertCacheTCryptCertCacheOpenSslTAesPrngAbstractTAesPrngOslTAesGcmAbstractTAesGcmOslTAesAbstractOslTAesOfbOslTAesEcbOslTAesCtrOslTAesCfbOslTAesCbcOslTAesAbstractEOpenSslEOpenSslHashEOpenSslCryptoEOpenSslAsymmetric
mormot.crypt.openssl class hierarchy

1.3. Objects implemented in the mormot.crypt.openssl unit

ObjectsDescription
EOpenSslAsymmetricException class raised by the sign/verify classes of this unit
EOpenSslCryptoException class raised by the AES classes of this unit
EOpenSslHashException class raised by the hashing classes of this unit
TAesAbstractOslHandle AES cypher/uncypher with chaining with OpenSSL 1.1
TAesCbcOslOpenSSL AES cypher/uncypher with Cipher-block chaining (CBC)
TAesCfbOslOpenSSL AES cypher/uncypher with Cipher feedback (CFB)
TAesCtrOslOpenSSL AES cypher/uncypher with 128-bit Counter mode (CTR)
TAesEcbOslOpenSSL AES cypher/uncypher without chaining (ECB)
TAesGcmOslOpenSSL AES-GCM cypher/uncypher
TAesOfbOslOpenSSL AES cypher/uncypher with Output feedback (OFB)
TAesOslReusable wrapper around OpenSSL Cipher process
TAesPrngOslTAesPrng-compatible class using OpenSSL 1.1
TCryptCertCacheOpenSslMaintain a cache of OpenSSL X.509 ICryptCert instances, from their DER/binary
TCryptPrivateKeyOpenSslStore an OpenSSL private key in ICryptPrivateKey format
TCryptPublicKeyOpenSslStore an OpenSSL public key in ICryptPublicKey format
TEcc256r1VerifyOslOpenSSL verification of a ECDSA signature using ECC secp256r1 cryptography
TJwtAbstractOslAbstract parent for OpenSSL JWT algorithms - never use this plain class!
TJwtEddsaOslImplements 'EdDSA' Ed25519 algorithm using OpenSSL
TJwtEs256KOslImplements 'ES256K' secp256k1 ECC algorithm using OpenSSL
TJwtEs256OslImplements 'ES256' secp256r1 ECC algorithm over SHA-256 using OpenSSL
TJwtEs384OslImplements 'ES384' secp384r1 ECC algorithm over SHA-384 using OpenSSL
TJwtEs512OslImplements 'ES512' ecp521r1 ECC algorithm over SHA-512 using OpenSSL
TJwtOpenSslAbstract parent for OpenSSL JWT algorithms - never use this plain class!
TJwtPs256OslImplements 'PS256' RSA-PSS algorithm over SHA-256 using OpenSSL
TJwtPs384OslImplements 'PS384' RSA-PSS algorithm over SHA-384 using OpenSSL
TJwtPs512OslImplements 'PS512' RSA-PSS algorithm over SHA-512 using OpenSSL
TJwtRs256OslImplements 'RS256' RSA algorithm over SHA-256 using OpenSSL
TJwtRs384OslImplements 'RS384' RSA algorithm over SHA-384 using OpenSSL
TJwtRs512OslImplements 'RS512' RSA algorithm over SHA-512 using OpenSSL
TOpenSslDigestAbstractAbstract parent multi-algorithm hashing/HMAC wrapper for OpenSSL
TOpenSslHashConvenient multi-algorithm wrapper for OpenSSL Hash algorithms
TOpenSslHmacConvenient multi-algorithm wrapper for OpenSSL HMAC algorithms

1.3.1. EOpenSslCrypto

EOpenSslCrypto = class(EOpenSsl)

Exception class raised by the AES classes of this unit


1.3.2. TAesPrngOsl

TAesPrngOsl = class(TAesPrngAbstract)

TAesPrng-compatible class using OpenSSL 1.1
- we abbreviate OpenSsl as Osl in class names for brevity
- may be used instead of TAesPrng if a "proven" generator is required - you could override MainAesPrng global variable
- but mormot.crypt.core TAesPrng is faster, especially for small output, and use a similar and proven 256-bit AES-CTR source of randomness:

  OpenSSL Random32 in 288.71ms i.e. 346,363/s, aver. 2us, 1.3 MB/s
  mORMot Random32 in 3.95ms i.e. 25,303,643/s, aver. 0us, 96.5 MB/s
  OpenSSL FillRandom in 240us, 397.3 MB/s
  mORMot FillRandom in 46us, 2 GB/s

constructor Create; override;

Initialize the CSPRNG using OpenSSL 1.1
- if the library is not available, will raise an Exception


class function IsAvailable: boolean; override;

Wrapper around function OpenSslIsAvailable


class function Main: TAesPrngAbstract; override;

Returns the single system-wide instance of TAesPrngOsl
- if you need to generate some random content, just call the TAesPrngOsl.Main.FillRandom() overloaded methods, or directly TAesPrngOsl.Fill() class methods


procedure FillRandom(Buffer: pointer; Len: PtrInt); override;

Fill a binary buffer with some pseudorandom data
- this method is thread-safe
- is just a wrapper around RAND_bytes() API call


1.3.3. TAesOsl

TAesOsl = object(TObject)

Reusable wrapper around OpenSSL Cipher process


Ctx: array[boolean] of PEVP_CIPHER_CTX;

Computed from TAesAbstractOsl.AlgoName


procedure Init(aOwner: TAesAbstract; aCipherName: PUtf8Char);

Set and reused in CallEvp()


1.3.4. TAesAbstractOsl

TAesAbstractOsl = class(TAesAbstract)

Handle AES cypher/uncypher with chaining with OpenSSL 1.1
- we abbreviate OpenSsl as Osl in class names for brevity
- use any of the inherited implementation, corresponding to the chaining mode required - TAesEcbOsl, TAesCbcOsl, TAesCfbOsl, TAesOfbOsl and TAesCtrOsl classes to handle in ECB, CBC, CFB, OFB and CTR mode (including PKCS7-like padding)
- those classes are re-entrant, i.e. that you can call the Encrypt* or Decrypt* methods on the same instance several times


destructor Destroy; override;

Release the used instance memory and resources


function Clone: TAesAbstract; override;

Circumvent Delphi bug about const aKey creates a new instance with the very same values
- directly copy the existing OpenSSL context for efficiency


function CloneEncryptDecrypt: TAesAbstract; override;

Compute a class instance similar to this one, for performing the reverse encryption/decryption process
- will return self to avoid creating two instances


class function IsAvailable: boolean; override;

Wrapper around function OpenSslIsAvailable
- actual cipher won't be checked until Create() since we need the keysize


procedure Decrypt(BufIn, BufOut: pointer; Count: cardinal); override;

Perform the AES un-cypher in the corresponding mode


procedure Encrypt(BufIn, BufOut: pointer; Count: cardinal); override;

Perform the AES cypher in the corresponding mode


1.3.5. TAesEcbOsl

TAesEcbOsl = class(TAesAbstractOsl)

OpenSSL AES cypher/uncypher without chaining (ECB)
- this mode is known to be less secure than the others


1.3.6. TAesCbcOsl

TAesCbcOsl = class(TAesAbstractOsl)

OpenSSL AES cypher/uncypher with Cipher-block chaining (CBC)


1.3.7. TAesCfbOsl

TAesCfbOsl = class(TAesAbstractOsl)

OpenSSL AES cypher/uncypher with Cipher feedback (CFB)
- our TAesCfb class is faster than OpenSSL on x86_64:

  mormot aes-128-cfb in 6.95ms i.e. 359247/s or 764.5 MB/s
  mormot aes-256-cfb in 9.40ms i.e. 265816/s or 565.7 MB/s
  openssl aes-128-cfb in 10.53ms i.e. 237326/s or 505 MB/s
  openssl aes-256-cfb in 13.18ms i.e. 189652/s or 403.6 MB/s

1.3.8. TAesOfbOsl

TAesOfbOsl = class(TAesAbstractOsl)

OpenSSL AES cypher/uncypher with Output feedback (OFB)
- our TAesOfb class is faster than OpenSSL on x86_64:

  mormot aes-128-ofb in 6.88ms i.e. 363002/s or 772.5 MB/s
  mormot aes-256-ofb in 9.37ms i.e. 266808/s or 567.8 MB/s
  openssl aes-128-ofb in 7.82ms i.e. 319693/s or 680.3 MB/s
  openssl aes-256-ofb in 10.39ms i.e. 240523/s or 511.8 MB/s

1.3.9. TAesCtrOsl

TAesCtrOsl = class(TAesAbstractOsl)

OpenSSL AES cypher/uncypher with 128-bit Counter mode (CTR)
- similar to TAesCtrNist, not our proprietary TAesCtrAny with a 64-bit CTR
- our TAesCtrNist class is faster than OpenSSL on x86_64:

  mormot aes-128-ctr in 1.99ms i.e. 1254390/s or 2.6 GB/s
  mormot aes-256-ctr in 2.64ms i.e. 945179/s or 1.9 GB/s
  openssl aes-128-ctr in 2.23ms i.e. 1121076/s or 2.3 GB/s
  openssl aes-256-ctr in 2.80ms i.e. 891901/s or 1.8 GB/s

1.3.10. TAesGcmOsl

TAesGcmOsl = class(TAesGcmAbstract)

OpenSSL AES-GCM cypher/uncypher
- implements AEAD (authenticated-encryption with associated-data) process via MacSetNonce/MacEncrypt or AesGcmAad/AesGcmFinal methods
- OpenSSL is faster than our TAesGcm class, but not so much:

  openssl aes-128-gcm in 2.86ms i.e. 874125/s or 1.8 GB/s
  openssl aes-256-gcm in 3.43ms i.e. 727590/s or 1.5 GB/s
  mormot aes-128-gcm in 3.45ms i.e. 722752/s or 1.5 GB/s
  mormot aes-256-gcm in 4.11ms i.e. 607385/s or 1.2 GB/s

- WARNING: AEAD associated information is currently unsupported by TAesGcmOsl, due to some obscure OpenSSL padding issue in our code - GMAC will be properly handled by TAesGcmOsl, but you should use plain TAesGcm instead if you really need to authenticate some associated information


function AesGcmFinal(var Tag: TAesBlock; TagLen: integer): boolean; override;

AES-GCM pure alternative to MacEncryptGetTag/MacDecryptCheckTag
- after Encrypt, fill tag with the GCM value of the data and return true
- after Decrypt, return true only if the GCM value of the data match tag


function Clone: TAesAbstract; override;

Creates a new instance with the very same values
- by design, our classes will use TAesGcmEngine stateless context, so this method will just copy the current fields to a new instance, by-passing the key creation step


function CloneEncryptDecrypt: TAesAbstract; override;

Compute a class instance similar to this one, for performing the reverse encryption/decryption process
- will return self to avoid creating two instances


procedure AesGcmAad(Buf: pointer; Len: integer); override;

AES-GCM pure alternative to MacSetNonce() - unsupported
- set the IV as usual (only the first 12 bytes will be used for GCM), then optionally append any AEAD data with this method; warning: you need to call Encrypt() once before - perhaps as Encrypt(nil, nil, 0)
- WARNING: AEAD associated information is currently unsupported by TAesGcmOsl, due to some obscure OpenSSL padding issue in our code - GMAC will be properly handled by TAesGcmOsl, but you should use plain TAesGcm instead if you really need to authenticate some associated information


1.3.11. EOpenSslHash

EOpenSslHash = class(EOpenSsl)

Exception class raised by the hashing classes of this unit


1.3.12. TOpenSslDigestAbstract

TOpenSslDigestAbstract = class(TObject)

Abstract parent multi-algorithm hashing/HMAC wrapper for OpenSSL


function Digest(Dest: pointer = nil): cardinal; virtual; abstract;

Computes the hash of all supplied messages
- store it internally the DigestValue buffer, or copy it into Dest buffer which is typically a THash256 or THash512 variable
- returns actual DigestValue/Dest buffer length, i.e. DigestSize


function DigestHex: RawUtf8;

Computes the Hash/HMAC of all supplied message as lowercase hexa chars


class function IsAvailable: boolean;

Wrapper around function OpenSslIsAvailable


procedure Update(Data: pointer; DataLength: integer); overload; virtual; abstract;

Call this method for each continuous message block
- iterate over all message blocks, then call Digest to retrieve the HMAC


procedure Update(const Data: RawByteString); overload;

Call this method for each continuous message block


property DigestSize: cardinal read fDigestSize;

How many bytes have been stored in DigestValues, after a call to Digest


property DigestValue: THash512Rec read fDigestValue;

Raw access to the final Message Digest, after a call to the Digest method
- if HashSize as supplied to Create() is bigger than 64, first bytes will be truncated in this field - you should specify a buffer to Digest() call


1.3.13. TOpenSslHash

TOpenSslHash = class(TOpenSslDigestAbstract)

Convenient multi-algorithm wrapper for OpenSSL Hash algorithms


constructor Create(const Algorithm: RawUtf8; HashSize: cardinal = 0);

Initialize the internal hashing structure for a specific algorithm
- Algorithm is one of `openssl list -digest-algorithms`
- if Algorithm is not specified, EVP_sha256 will be used
- for XOF hash functions such as 'shake256', the hashSize option can be used to specify the desired output length in bytes
- raise an EOpenSslHash exception on unknown/unsupported algorithm


destructor Destroy; override;

Release the digest context


function Digest(Dest: pointer = nil): cardinal; override;

Computes the hash of all supplied messages
- store it internally the DigestValue buffer, or copy it into Dest buffer which is typically a THash256 or THash512 variable
- returns actual DigestValue/Dest buffer length, i.e. DigestSize


class function Hash(const Algorithm: RawUtf8; const Data: RawByteString; HashSize: cardinal = 0): RawUtf8;

Compute the message authentication code using `Algorithm` as hash function


procedure Update(Data: pointer; DataLength: integer); override;

Call this method for each continuous message block
- iterate over all message blocks, then call Digest to retrieve the Hash


1.3.14. TOpenSslHmac

TOpenSslHmac = class(TOpenSslDigestAbstract)

Convenient multi-algorithm wrapper for OpenSSL HMAC algorithms


constructor Create(const Algorithm: RawUtf8; const Key: RawByteString); overload;

Initialize the internal HMAC structure for a specific Algorithm and Key


constructor Create(const Algorithm: RawUtf8; Key: pointer; KeyLength: cardinal); overload;

Initialize the internal HMAC structure for a specific Algorithm and Key
- Algorithm is one of `openssl list -digest-algorithms`
- if Algorithm is not specified, EVP_sha256 will be used
- Key/KeyLen define the HMAC associated salt
- raise an EOpenSslHash exception on unknown/unsupported algorithm


destructor Destroy; override;

Release the digest context


function Digest(Dest: pointer = nil): cardinal; override;

Computes the HMAC of all supplied messages
- store it internally the DigestValue buffer, or copy it into Dest buffer which is typically a THash256 or THash512 variable
- returns actual DigestValue/Dest buffer length, i.e. DigestSize


class function Hmac(const Algorithm: RawUtf8; const Data, Key: RawByteString): RawUtf8; overload;

Compute the HMAC using `algorithm` as hash function


class function Hmac(const Algorithm: RawUtf8; const Data: RawByteString; Key: pointer; KeyLength: cardinal): RawUtf8; overload;

Compute the HMAC using `algorithm` as hash function


procedure Update(Data: pointer; DataLength: integer); override;

Call this method for each continuous message block
- iterate over all message blocks, then call Digest to retrieve the Hash


1.3.15. EOpenSslAsymmetric

EOpenSslAsymmetric = class(EOpenSsl)

Exception class raised by the sign/verify classes of this unit


1.3.16. TEcc256r1VerifyOsl

TEcc256r1VerifyOsl = class(TEcc256r1VerifyAbstract)

OpenSSL verification of a ECDSA signature using ECC secp256r1 cryptography
- assigned to TEcc256r1Verify global meta-class at startup


constructor Create(const pub: TEccPublicKey); override;

Initialize the verifier with a given ECC compressed public key


destructor Destroy; override;

Finalize this instance


function Verify(const hash: TEccHash; const sign: TEccSignature): boolean; override;

Validate a signature against a hash using ECC


1.3.17. TJwtOpenSsl

TJwtOpenSsl = class(TJwtAsym)

Abstract parent for OpenSSL JWT algorithms - never use this plain class!


constructor Create(const aJwtAlgorithm, aHashAlgorithm: RawUtf8; aGenEvpType, aGenBitsOrCurve: integer; const aPrivateKey, aPublicKey: RawByteString; const aPrivateKeyPassword, aPublicKeyPassword: SpiUtf8; aClaims: TJwtClaims; const aAudience: array of RawUtf8; aExpirationMinutes: integer = 0; aIDIdentifier: TSynUniqueIdentifierProcess = 0; aIDObfuscationKey: RawUtf8 = ''; aIDObfuscationKeyNewKdf: integer = 0); reintroduce;

Initialize the JWT processing instance using any supported OpenSSL algorithm


destructor Destroy; override;

Finalize the instance


class function IsAvailable: boolean; virtual;

Wrapper around OpenSslIsAvailable() function


property AsymAlgo: TCryptAsymAlgo read fAsymAlgo;

The asymmetric algorithm, as defined by inherted classes


property HashAlgorithm: RawUtf8 read fHashAlgorithm;

The OpenSSL hash algorithm, as supplied to the constructor


1.3.18. TJwtAbstractOsl

TJwtAbstractOsl = class(TJwtOpenSsl)

Abstract parent for OpenSSL JWT algorithms - never use this plain class!
- inherited classes implement all official algorithms from https://jwt.io
- we abbreviate OpenSsl as Osl in class names for brevity
- some numbers from our regresssion tests on Linux x86_64 for JWT validation:

 100 RS256 in 2.03ms i.e. 47.8K/s, aver. 20us
 100 RS384 in 1.99ms i.e. 48.9K/s, aver. 19us
 100 RS512 in 1.99ms i.e. 48.9K/s, aver. 19us
 100 PS256 in 2.30ms i.e. 42.3K/s, aver. 23us
 100 PS384 in 2.26ms i.e. 43.1K/s, aver. 22us
 100 PS512 in 2.75ms i.e. 35.4K/s, aver. 27us
 100 ES256 in 8.64ms i.e. 11.3K/s, aver. 86us
 100 ES384 in 81.43ms i.e. 1.1K/s, aver. 814us
 100 ES512 in 59.81ms i.e. 1.6K/s, aver. 598us
 100 ES256K in 40.43ms i.e. 2.4K/s, aver. 404us
 100 EdDSA in 11.55ms i.e. 8.4K/s, aver. 115us

constructor Create( const aPrivateKey, aPublicKey: RawByteString; const aPrivateKeyPassword, aPublicKeyPassword: SpiUtf8; aClaims: TJwtClaims; const aAudience: array of RawUtf8; aExpirationMinutes: integer = 0; aIDIdentifier: TSynUniqueIdentifierProcess = 0; aIDObfuscationKey: RawUtf8 = ''; aIDObfuscationKeyNewKdf: integer = 0); reintroduce;

Initialize the JWT processing instance calling SetAlgorithms abstract method
- the supplied key(s) could be in PEM or raw DER binary format
- the supplied set of claims are expected to be defined in the JWT payload
- aAudience are the allowed values for the jrcAudience claim
- aExpirationMinutes is the deprecation time for the jrcExpirationTime claim
- aIDIdentifier and aIDObfuscationKey/aIDObfuscationKeyNewKdf are passed to a TSynUniqueIdentifierGenerator instance used for jrcJwtID claim


class function IsAvailable: boolean; override;

Wrapper around OpenSslSupports() function


class procedure GenerateBinaryKeys(out PrivateKey, PublicKey: RawByteString);

Generate a private/public keys pair for this algorithm in raw DER format
- the new key will have RSA_DEFAULT_GENERATION_BITS, i.e. 2048-bit


class procedure GenerateKeys(out PrivateKey, PublicKey: RawUtf8);

Generate a private/public keys pair for this algorithm in PEM text format
- the new key will have RSA_DEFAULT_GENERATION_BITS, i.e. 2048-bit


1.3.19. TJwtEs256Osl

TJwtEs256Osl = class(TJwtAbstractOsl)

Implements 'ES256' secp256r1 ECC algorithm over SHA-256 using OpenSSL
- note that our TJwtEs256 class is slightly faster on Linux x86_64:

 TJwtEs256 pascal:   100 ES256 in 33.57ms i.e. 2.9K/s, aver. 335us
 TJwtEs256 OpenSSL:  100 ES256 in 6.90ms i.e. 14.1K/s, aver. 69us
 TJwtEs256Osl:       100 ES256 in 8.64ms i.e. 11.3K/s, aver. 86us

1.3.20. TJwtEs384Osl

TJwtEs384Osl = class(TJwtAbstractOsl)

Implements 'ES384' secp384r1 ECC algorithm over SHA-384 using OpenSSL


1.3.21. TJwtEs512Osl

TJwtEs512Osl = class(TJwtAbstractOsl)

Implements 'ES512' ecp521r1 ECC algorithm over SHA-512 using OpenSSL


1.3.22. TJwtEs256KOsl

TJwtEs256KOsl = class(TJwtAbstractOsl)

Implements 'ES256K' secp256k1 ECC algorithm using OpenSSL


1.3.23. TJwtRs256Osl

TJwtRs256Osl = class(TJwtAbstractOsl)

Implements 'RS256' RSA algorithm over SHA-256 using OpenSSL


1.3.24. TJwtRs384Osl

TJwtRs384Osl = class(TJwtAbstractOsl)

Implements 'RS384' RSA algorithm over SHA-384 using OpenSSL


1.3.25. TJwtRs512Osl

TJwtRs512Osl = class(TJwtAbstractOsl)

Implements 'RS512' RSA algorithm over SHA-512 using OpenSSL


1.3.26. TJwtPs256Osl

TJwtPs256Osl = class(TJwtAbstractOsl)

Implements 'PS256' RSA-PSS algorithm over SHA-256 using OpenSSL


1.3.27. TJwtPs384Osl

TJwtPs384Osl = class(TJwtAbstractOsl)

Implements 'PS384' RSA-PSS algorithm over SHA-384 using OpenSSL


1.3.28. TJwtPs512Osl

TJwtPs512Osl = class(TJwtAbstractOsl)

Implements 'PS512' RSA-PSS algorithm over SHA-512 using OpenSSL


1.3.29. TJwtEddsaOsl

TJwtEddsaOsl = class(TJwtAbstractOsl)

Implements 'EdDSA' Ed25519 algorithm using OpenSSL


1.3.30. TCryptPublicKeyOpenSsl

TCryptPublicKeyOpenSsl = class(TCryptPublicKey)

Store an OpenSSL public key in ICryptPublicKey format
- set to mormot.crypt.secure CryptPublicKey[] factories by RegisterOpenSsl


1.3.31. TCryptPrivateKeyOpenSsl

TCryptPrivateKeyOpenSsl = class(TCryptPrivateKey)

Store an OpenSSL private key in ICryptPrivateKey format
- set to mormot.crypt.secure CryptPrivateKey[] factories by RegisterOpenSsl


1.3.32. TCryptCertCacheOpenSsl

TCryptCertCacheOpenSsl = class(TCryptCertCache)

Maintain a cache of OpenSSL X.509 ICryptCert instances, from their DER/binary
- defined here so that you could use OpenSSL for your certificates process


1.4. Types implemented in the mormot.crypt.openssl unit

1.4.1. TJwtAbstractOslClass

TJwtAbstractOslClass = class of TJwtAbstractOsl;

Meta-class of all OpenSSL JWT algorithms


1.5. Constants implemented in the mormot.crypt.openssl unit

1.5.1. CAA_BITSORCURVE

CAA_BITSORCURVE: array[TCryptAsymAlgo] of integer = ( NID_X9_62_prime256v1, NID_secp384r1, NID_secp521r1, NID_secp256k1, RSA_DEFAULT_GENERATION_BITS, RSA_DEFAULT_GENERATION_BITS, RSA_DEFAULT_GENERATION_BITS, RSA_DEFAULT_GENERATION_BITS, RSA_DEFAULT_GENERATION_BITS, RSA_DEFAULT_GENERATION_BITS, 0);

CaaES256 caaES384 caaES512 caaES256K caaRS256 caaRS384 caaRS512 caaPS256 caaPS384 caaPS512 caaEdDSA


1.6. Functions or procedures implemented in the mormot.crypt.openssl unit

Functions or proceduresDescription
ecc_make_key_oslMormot.crypt.ecc256r1 compatible function for asymmetric key generation
ecdh_shared_secret_oslMormot.crypt.ecc256r1 compatible function for ECDH shared secret computation
ecdsa_sign_oslMormot.crypt.ecc256r1 compatible function for asymmetric key signature
ecdsa_verify_oslMormot.crypt.ecc256r1 compatible function for asymmetric key verification
OpenSslGenerateBinaryKeysGenerate a public/private pair of keys in raw DER binary format
OpenSslGenerateKeysGenerate a public/private pair of keys in PEM text format
OpenSslGenerateKeysGenerate a public/private pair of keys in raw OpenSSL format
OpenSslGetMdRetrieve a low-level PEVP_MD digest from mORMot TCryptAsymAlgo enum
OpenSslGetMdRetrieve a low-level PEVP_MD digest from mORMot THashAlgo enum
OpenSslGetMdByNameRetrieve a low-level PEVP_MD digest from its algorithm name
OpenSslLoadCompute a new ICryptCert OpenSSL instance from DER or PEM input
OpenSslSignAsymmetric digital signature of some Message using a given PrivateKey
OpenSslSupportsCheck if a TCryptAsymAlgo of public/private pair of keys is supported
OpenSslSupportsCheck if an OpenSSL given type of public/private pair of keys is supported
OpenSslVerifyAsymmetric digital verification of some Message using a given PublicKey
OpenSslX509ParseHigh-level function to decode X.509 certificate main properties using OpenSSL
RegisterOpenSslCall once at program startup to use OpenSSL when its performance matters
X509AlgoGuess the asymmetric algorithm of this OpenSSL X.509 certificate

1.6.1. ecc_make_key_osl

function ecc_make_key_osl(out PublicKey: TEccPublicKey; out PrivateKey: TEccPrivateKey): boolean;

Mormot.crypt.ecc256r1 compatible function for asymmetric key generation
- this OpenSSL-powered function will replace our slower mormot.crypt.ecc256r1

 OpenSSL: 300 Ecc256r1MakeKey in 7.75ms i.e. 38,664/s, aver. 25us
 mORMot:  300 Ecc256r1MakeKey in 255ms i.e. 1,176/s, aver. 850us

- directly access OpenSSL prime256v1, so faster than OpenSslGenerateKeys()


1.6.2. ecdh_shared_secret_osl

function ecdh_shared_secret_osl(const PublicKey: TEccPublicKey; const PrivateKey: TEccPrivateKey; out Secret: TEccSecretKey): boolean;

Mormot.crypt.ecc256r1 compatible function for ECDH shared secret computation
- this OpenSSL-powered function will replace our slower pascal/c code

 OpenSSL: 598 Ecc256r1SharedSecret in 67.98ms i.e. 8,796/s, aver. 113us
 mORMot:  598 Ecc256r1SharedSecret in 537.95ms i.e. 1,111/s, aver. 899us

1.6.3. ecdsa_sign_osl

function ecdsa_sign_osl(const PrivateKey: TEccPrivateKey; const Hash: TEccHash; out Signature: TEccSignature): boolean;

Mormot.crypt.ecc256r1 compatible function for asymmetric key signature
- this OpenSSL-powered function will replace our slower pascal/c code

 OpenSSL: 300 Ecc256r1Sign in 11.66ms i.e. 25,711/s, aver. 38us
 mORMot:  300 Ecc256r1Sign in 262.72ms i.e. 1,141/s, aver. 875us

- directly access OpenSSL prime256v1, so faster than OpenSslSign()


1.6.4. ecdsa_verify_osl

function ecdsa_verify_osl(const PublicKey: TEccPublicKey; const Hash: TEccHash; const Signature: TEccSignature): boolean;

Mormot.crypt.ecc256r1 compatible function for asymmetric key verification
- this OpenSSL-powered function will replace our slower pascal/c code

 OpenSSL: 300 Ecc256r1Verify in 41.32ms i.e. 7,260/s, aver. 137us
 mORMot:  300 Ecc256r1Verify in 319.32ms i.e. 939/s, aver. 1.06ms

- directly access OpenSSL prime256v1, so faster than OpenSslVerify()


1.6.5. OpenSslGenerateBinaryKeys

procedure OpenSslGenerateBinaryKeys(EvpType, BitsOrCurve: integer; out PrivateKey, PublicKey: RawByteString; const PrivateKeyPassWord: SpiUtf8 = '');

Generate a public/private pair of keys in raw DER binary format
- if EvpType is EVP_PKEY_DSA, EVP_PKEY_DH or EVP_PKEY_RSA or EVP_PKEY_RSA_PSS, BitsOrCurve is the number of bits of the key
- if EvpType is EVP_PKEY_EC, BitsOrCurve is the Elliptic curve NID (e.g. NID_X9_62_prime256v1)
- if EvpType is EVP_PKEY_ED25519, BitsOrCurve is ignored


1.6.6. OpenSslGenerateKeys

function OpenSslGenerateKeys(EvpType, BitsOrCurve: integer): PEVP_PKEY; overload;

Generate a public/private pair of keys in raw OpenSSL format
- if EvpType is EVP_PKEY_DSA, EVP_PKEY_DH or EVP_PKEY_RSA or EVP_PKEY_RSA_PSS, BitsOrCurve is the number of bits of the key
- if EvpType is EVP_PKEY_EC, BitsOrCurve is the curve NID (e.g. NID_X9_62_prime256v1)
- if EvpType is EVP_PKEY_ED25519, BitsOrCurve is ignored
- caller should result.Free once done with the private key returned instance


1.6.7. OpenSslGenerateKeys

procedure OpenSslGenerateKeys(EvpType, BitsOrCurve: integer; out PrivateKey, PublicKey: RawUtf8; const PrivateKeyPassWord: SpiUtf8 = ''); overload;

Generate a public/private pair of keys in PEM text format
- if EvpType is EVP_PKEY_DSA, EVP_PKEY_DH or EVP_PKEY_RSA or EVP_PKEY_RSA_PSS, BitsOrCurve is the number of bits of the key
- if EvpType is EVP_PKEY_EC, BitsOrCurve is the Elliptic curve NID (e.g. NID_X9_62_prime256v1)
- if EvpType is EVP_PKEY_ED25519, BitsOrCurve is ignored


1.6.8. OpenSslGetMd

function OpenSslGetMd(Algorithm: THashAlgo): PEVP_MD; overload;

Retrieve a low-level PEVP_MD digest from mORMot THashAlgo enum
- returns nil if not found, e.g. if OpenSsl is not available


1.6.9. OpenSslGetMd

function OpenSslGetMd(Algorithm: TCryptAsymAlgo): PEVP_MD; overload;

Retrieve a low-level PEVP_MD digest from mORMot TCryptAsymAlgo enum
- returns nil if not found, e.g. if OpenSsl is not available


1.6.10. OpenSslGetMdByName

function OpenSslGetMdByName(const Algorithm: RawUtf8; const Caller: shortstring): PEVP_MD; overload;

Retrieve a low-level PEVP_MD digest from its algorithm name
- raise an EOpenSslHash if this algorithm is not found


1.6.11. OpenSslLoad

function OpenSslLoad(const Cert: RawByteString): ICryptCert;

Compute a new ICryptCert OpenSSL instance from DER or PEM input
- returns nil if the input is not correct or not supported
- returns non-nil TCryptCertOpenSsl instance from function LoadCertificate()
- will guess the proper TCryptCertAlgoOpenSsl to use for the ICryptCert
- called e.g. by TCryptCertCacheOpenSsl


1.6.12. OpenSslSign

function OpenSslSign(const Algorithm: RawUtf8; Message, PrivateKey: pointer; MessageLen, PrivateKeyLen: integer; out Signature: RawByteString; const PrivateKeyPassword: SpiUtf8 = ''): cardinal;

Asymmetric digital signature of some Message using a given PrivateKey
- if Algorithm is '', EVP_sha256 will be used as message Digest
- if Algorithm is 'null', no Digest is done before signature - which is mandatory e.g. for ed25519 which uses internally SHA-512
- returns 0 on error, or the result Signature size in bytes


1.6.13. OpenSslSupports

function OpenSslSupports(EvpType: integer): boolean; overload;

Check if an OpenSSL given type of public/private pair of keys is supported
- some older OpenSSL versions do not support e.g. EVP_PKEY_ED25519


1.6.14. OpenSslSupports

function OpenSslSupports(Algo: TCryptAsymAlgo): boolean; overload;

Check if a TCryptAsymAlgo of public/private pair of keys is supported


1.6.15. OpenSslVerify

function OpenSslVerify(const Algorithm: RawUtf8; const PublicKeyPassword: SpiUtf8; Message, PublicKey, Signature: pointer; MessageLen, PublicKeyLen, SignatureLen: integer; const Engine: RawUtf8 = ''): boolean;

Asymmetric digital verification of some Message using a given PublicKey
- if Algorithm is '', EVP_sha256 will be used as message Digest
- if Algorithm is 'null', no Digest is done before signature - which is mandatory e.g. for ed25519 which uses internally SHA-512
- returns false on error, or true if the Message has been authenticated


1.6.16. OpenSslX509Parse

function OpenSslX509Parse(const Cert: RawByteString; out Info: TX509Parsed): boolean;

High-level function to decode X.509 certificate main properties using OpenSSL
- assigned to mormot.core.secure X509Parse() redirection by RegisterOpenSsl


1.6.17. RegisterOpenSsl

procedure RegisterOpenSsl;

Call once at program startup to use OpenSSL when its performance matters
- to be typically called after function OpenSslInitialize() by your project
- redirects TAesGcmFast (and TAesCtrFast on i386) globals to OpenSSL
- redirects raw mormot.crypt.ecc256r1 functions to use OpenSSL which is much faster than our stand-alone pure pascal version
- register OpenSSL for our Asym() and Cert() high-level factory, and also for CryptPublicKey[] and CryptPrivateKey[]
- RegisterX509 from mormot.crypt.x509.pas can be called after this procedure, to register TCryptCertAlgoX509 with ckaEcc384, ckaEcc512 and ckaEdDSA


1.6.18. X509Algo

function X509Algo(x: PX509): TCryptAsymAlgo;

Guess the asymmetric algorithm of this OpenSSL X.509 certificate
- returns nil if x is nil
- raise an EOpenSslCert if x has an unsupported algorithm
- warning: caaES256K can not be distinguished from caaES256
- is defined here because TCryptAsymAlgo is from mormot.crypt.secure.pas which does not fit in the low-level mormot.lib.openssl.pas unit