Visitar URL original
libssh2/src/HACKING-CRYPTO.md at master · chuckx/libssh2 · GitHub
Skip to content

Latest commit

 

History

History
833 lines (667 loc) · 28 KB

HACKING-CRYPTO.md

File metadata and controls

833 lines (667 loc) · 28 KB

Definitions needed to implement a specific crypto library

This document offers some hints about implementing a new crypto library interface.

A crypto library interface consists of at least a header file, defining entities referenced from the libssh2 core modules. Real code implementation (if needed), is left at the implementor's choice.

This document lists the entities that must/may be defined in the header file.

Procedures listed as "void" may indeed have a result type: the void indication indicates the libssh2 core modules never use the function result.

0) Build system.

Adding a crypto backend to the autotools build system (./configure) is easy:

0.1) Add logic to configure.ac

Search for an existing backend (e.g. 'openssl'), duplicate each occurrence and use the new backend's name in them.

0.2) Add an m4_case stanza to LIBSSH2_CRYPTO_CHECK in acinclude.m4

This must check for all required libraries, and if found set and AC_SUBST a variable with the library linking flags. The recommended method is to use LIBSSH2_LIB_HAVE_LINKFLAGS from LIBSSH2_CRYPTO_CHECK, which automatically creates and handles a --with-$newname-prefix option and sets an LTLIBNEWNAME variable on success.

0.3) Add new header to src/Makefile.inc

0.4) Add a new block in configure.ac

elif test "$found_crypto" = "newname"; then
  LIBS="${LIBS} ${LTLIBNEWNAME}"

0.5) Add CMake detection logic to CMakeLists.txt

1) Crypto library initialization/termination

void ssh2_crypto_init(void);

Initializes the crypto library. May be an empty macro if not needed.

void ssh2_crypto_exit(void);

Terminates the crypto library use. May be an empty macro if not needed.

1.1) Crypto runtime detection

The libssh2_crypto_engine_t enum must include the new engine, and libssh2_crypto_engine() must return it when it is built in.

2) HMAC

ssh2_hmac_ctx: Type of an HMAC computation context. Generally a struct. Used for all hash algorithms.

ssh2_hmac_alg: Type of a HMAC algorithm.

Algorithm constants:

  • SSH2_SHA1_HMAC (optional)
  • SSH2_SHA256_HMAC
  • SSH2_SHA512_HMAC
  • SSH2_MD5_HMAC (optional)
  • SSH2_RIPEMD160_HMAC (optional)
int ssh2_hmac_init(ssh2_hmac_ctx *ctx, ssh2_hmac_alg alg,
                   void *key, size_t key_len);

Initializes the HMAC computation context ctx for a computation using the key_len-byte key. Is invoked right after ssh2_hmac_ctx_init(). Called before setting-up the hash algorithm. Must return 1 for success and 0 for failure.

int ssh2_hmac_update(ssh2_hmac_ctx *ctx,
                     const void *input, int input_len);

Continue computation of an HMAC on datalen bytes at input using context ctx. May be provided as a macro. Must return 1 for success and 0 for failure.

int ssh2_hmac_final(ssh2_hmac_ctx *ctx, void *mac, size_t mac_len);

Get the computed HMAC from context ctx into the mac output buffer. The minimum data buffer size depends on the HMAC hash algorithm. Must return 1 for success and 0 for failure.

void ssh2_hmac_cleanup(ssh2_hmac_ctx *ctx);

Releases the HMAC computation context at ctx.

3) Hash algorithms

ssh2_hash_ctx: Type of a hash computation context. Generally a struct.

ssh2_hash_alg: Type of a hash algorithm.

Algorithm constants:

  • SSH2_SHA1_ALG (optional)
  • SSH2_SHA256_ALG
  • SSH2_SHA384_ALG
  • SSH2_SHA512_ALG
  • SSH2_MD5_ALG (optional)
int ssh2_hash_init(ssh2_hash_ctx *ctx, ssh2_hash_alg alg);

Initializes the hash computation context at ctx. Returns 1 for success and 0 for failure

int ssh2_hash_update(ssh2_hash_ctx ctx,
                     const unsigned char *input, size_t input_len);

Continue computation of hash on input_len bytes at input using context ctx. May be provided as a macro. Must return 1 for success and 0 for failure.

int ssh2_hash_final(ssh2_hash_ctx ctx,
                    unsigned char *digest, size_t digest_len);

Get the computed hash digest from context ctx and store it into the digest output buffer. Release the context. Must return 1 for success and 0 for failure.

4) Bidirectional key ciphers

ssh2_cipher_ctx: Type of a cipher computation context.

SSH2_CIPHER_T(name);

Macro defining name as storage identifying a cipher algorithm for the crypto library interface. No trailing semicolon.

int ssh2_cipher_init(ssh2_cipher_ctx *h,
                     SSH2_CIPHER_T(algo),
                     unsigned char *iv,
                     unsigned char *secret,
                     int encrypt);

Creates a cipher context for the given algorithm with the initialization vector iv and the secret key secret. Prepare for encryption or decryption depending on encrypt. Return 0 if OK, else -1. This procedure is already prototyped in crypto.h.

int ssh2_cipher_crypt(ssh2_cipher_ctx *ctx,
                      SSH2_CIPHER_T(algo),
                      int encrypt,
                      unsigned char *block,
                      size_t blocksize,
                      int firstlast);

Encrypt or decrypt in-place data at (block, blocksize) using the given context and/or algorithm. Return 0 if OK, else -1. This procedure is already prototyped in crypto.h.

void ssh2_cipher_dtor(ssh2_cipher_ctx *ctx);

Release cipher context at ctx.

4.1) AES

4.1.1) AES in CBC block mode

LIBSSH2_AES: define as 1 if the crypto library supports AES in CBC mode, else 0. If defined as 0, the rest of this section can be omitted.

ssh2_cipher_aes128: AES-128-CBC algorithm identifier initializer. define with constant value of type SSH2_CIPHER_T().

ssh2_cipher_aes192: AES-192-CBC algorithm identifier initializer. define with constant value of type SSH2_CIPHER_T().

ssh2_cipher_aes256: AES-256-CBC algorithm identifier initializer. define with constant value of type SSH2_CIPHER_T().

4.1.2) AES in CTR block mode

LIBSSH2_AES_CTR: define as 1 if the crypto library supports AES in CTR mode, else 0. If defined as 0, the rest of this section can be omitted.

ssh2_cipher_aes128ctr: AES-128-CTR algorithm identifier initializer. define with constant value of type SSH2_CIPHER_T().

ssh2_cipher_aes192ctr: AES-192-CTR algorithm identifier initializer. define with constant value of type SSH2_CIPHER_T().

ssh2_cipher_aes256ctr: AES-256-CTR algorithm identifier initializer. define with constant value of type SSH2_CIPHER_T().

4.2) Blowfish in CBC block mode

LIBSSH2_BLOWFISH: define as 1 if the crypto library supports blowfish in CBC mode, else 0. If defined as 0, the rest of this section can be omitted.

ssh2_cipher_blowfish: Blowfish-CBC algorithm identifier initializer. define with constant value of type SSH2_CIPHER_T().

4.3) RC4

LIBSSH2_RC4: define as 1 if the crypto library supports RC4 (arcfour), else 0. If defined as 0, the rest of this section can be omitted.

ssh2_cipher_arcfour: RC4 algorithm identifier initializer. define with constant value of type SSH2_CIPHER_T().

4.4) CAST5 in CBC block mode

LIBSSH2_CAST: define 1 if the crypto library supports cast, else 0. If defined as 0, the rest of this section can be omitted.

ssh2_cipher_cast5 CAST5-CBC algorithm identifier initializer. define with constant value of type SSH2_CIPHER_T().

4.5) Triple DES in CBC block mode

LIBSSH2_3DES: define as 1 if the crypto library supports TripleDES in CBC mode, else 0. If defined as 0, the rest of this section can be omitted.

ssh2_cipher_3des: TripleDES-CBC algorithm identifier initializer. define with constant value of type SSH2_CIPHER_T().

5) Diffie-Hellman support

SSH2_DH_GEX_MINGROUP: The minimum Diffie-Hellman group length in bits supported by the backend. Usually defined as 2048.

SSH2_DH_GEX_OPTGROUP: The preferred Diffie-Hellman group length in bits. Usually defined as 4096.

SSH2_DH_GEX_MAXGROUP: The maximum Diffie-Hellman group length in bits supported by the backend. Usually defined as 8192.

SSH2_DH_MAX_MODULUS_BITS: The maximum Diffie-Hellman modulus bit count accepted from the server. This value must be supported by the backend. Usually 16384.

5.1) Diffie-Hellman context

ssh2_dh_ctx: Type of a Diffie-Hellman computation context. Must always be defined.

5.2) Diffie-Hellman computation procedures

void ssh2_dh_init(ssh2_dh_ctx *dhctx);

Initializes the Diffie-Hellman context at dhctx. No effective context creation needed here.

int ssh2_dh_key_pair(ssh2_dh_ctx *dhctx, ssh2_bn *public,
                     ssh2_bn *g, ssh2_bn *p, int group_order,
                     ssh2_bn_ctx *bnctx);

Generates a Diffie-Hellman key pair using base g, prime p and the given group_order. Can use the given big number context bnctx if needed. The private key is stored as opaque in the Diffie-Hellman context *dhctx and the public key is returned in public. 0 is returned upon success, else -1.

int ssh2_dh_secret(ssh2_dh_ctx *dhctx, ssh2_bn *secret,
                   ssh2_bn *f, ssh2_bn *p, ssh2_bn_ctx *bnctx)

Computes the Diffie-Hellman secret from the previously created context *dhctx, the public key f from the other party and the same prime p used at context creation. The result is stored in secret. 0 is returned upon success, else -1.

void ssh2_dh_dtor(ssh2_dh_ctx *dhctx)

Destroys Diffie-Hellman context at dhctx and resets its storage.

6) Big numbers

Positive multi-byte integers support is sufficient.

6.1) Computation contexts

This has a real meaning if the big numbers computations need some context storage. If not, use a dummy type and functions (macros).

ssh2_bn_ctx: Type of multiple precision computation context. May not be empty. if not used, define as char, for example.

ssh2_bn_ctx ssh2_bn_ctx_new(void);

Returns a new multiple precision computation context.

void ssh2_bn_ctx_free(ssh2_bn_ctx ctx);

Releases a multiple precision computation context.

6.2) Computation support

ssh2_bn: Type of multiple precision numbers (aka bignumbers or huge integers) for the crypto library.

ssh2_bn *ssh2_bn_init(void);

Creates a multiple precision number (preset to zero).

ssh2_bn *ssh2_bn_init_from_bin(void);

Create a multiple precision number intended to be set by the ssh2_bn_from_bin() function (see below). Unlike ssh2_bn_init(), this code may be a dummy initializer if the ssh2_bn_from_bin() actually allocates the number. Returns a value of type ssh2_bn *.

void ssh2_bn_free(ssh2_bn *bn);

Destroys the multiple precision number at bn.

size_t ssh2_bn_bytes(ssh2_bn *bn);

Get the number of bytes needed to store the bits of the multiple precision number at bn.

size_t ssh2_bn_bits(ssh2_bn *bn);

Returns the number of bits of multiple precision number at bn.

int ssh2_bn_set_word(ssh2_bn *bn, uint32_t word);

Sets the value of bn to word. Returns 1 on success, 0 otherwise.

ssh2_bn *ssh2_bn_from_bin(ssh2_bn *bn, const unsigned char *bin, size_t len);

Converts the positive integer in big-endian form of length len at bin into an ssh2_bn and place it in bn. If bn is NULL, a new ssh2_bn is created.

Returns a pointer to target ssh2_bn or NULL if error.

int ssh2_bn_to_bin(ssh2_bn *bn, unsigned char *bin);

Converts the absolute value of bn into big-endian form and store it at bin. val must point to ssh2_bn_bytes(bn) bytes of memory. Returns the length of the big-endian number.

7) Private key algorithms

Format of an RSA public key:

  1. "ssh-rsa".
  2. RSA exponent, MSB first, with high order bit = 0.
  3. RSA modulus, MSB first, with high order bit = 0.

Each item is preceded by its 32-bit byte length, MSB first.

Format of a DSA public key:

  1. "ssh-dss".
  2. p, MSB first, with high order bit = 0.
  3. q, MSB first, with high order bit = 0.
  4. g, MSB first, with high order bit = 0.
  5. pub_key, MSB first, with high order bit = 0.

Each item is preceded by its 32-bit byte length, MSB first.

Format of an ECDSA public key:

  1. ecdsa-sha2-nistp256 or ecdsa-sha2-nistp384 or ecdsa-sha2-nistp521.
  2. domain: nistp256, nistp384 or nistp521 matching a).
  3. raw public key ("octal").

Each item is preceded by its 32-bit byte length, MSB first.

Format of an ED25519 public key:

  1. "ssh-ed25519".
  2. raw key (32 bytes).

Each item is preceded by its 32-bit byte length, MSB first.

int ssh2_pub_privkey(LIBSSH2_SESSION *session, char **method,
                     unsigned char **pubkeydata, size_t *pubkeydata_len,
                     const char *privkeyfile,
                     const char *privkeyblob, size_t privkeyblob_len,
                     const char *passphrase);

Gets a private key from file privkeyfile, or bytes at (privkeyblob, privkeyblob_len) and extracts the public key --> (pubkeydata, pubkeydata_len). Store the associated method (e.g., ssh-rsa, ssh-ed25519) into *method. Both buffers have to be allocated using SSH2_ALLOC(). Returns 0 if OK, else -1. This procedure is already prototyped in crypto.h.

7.1) RSA

LIBSSH2_RSA: define as 1 if the crypto library supports RSA, else 0. If defined as 0, the rest of this section can be omitted.

ssh2_rsa_ctx: Type of an RSA computation context. Generally a struct.

int ssh2_rsa_new(ssh2_rsa_ctx **rsa,
                 const unsigned char *edata, size_t elen,
                 const unsigned char *ndata, size_t nlen,
                 const unsigned char *ddata, size_t dlen,
                 const unsigned char *pdata, size_t plen,
                 const unsigned char *qdata, size_t qlen,
                 const unsigned char *e1data, size_t e1len,
                 const unsigned char *e2data, size_t e2len,
                 const unsigned char *coeffdata, size_t coefflen);

Creates a new context for RSA computations from key source values:

  • pdata, plen Prime number p. Only used if private key known (ddata).
  • qdata, qlen Prime number q. Only used if private key known (ddata).
  • ndata, nlen Modulus n.
  • edata, elen Exponent e.
  • ddata, dlen e^-1 % phi(n) = private key. May be NULL if unknown.
  • e1data, e1len dp = d % (p-1). Only used if private key known (ddata).
  • e2data, e2len dq = d % (q-1). Only used if private key known (ddata).
  • coeffdata, coefflen q^-1 % p. Only used if private key known.

Returns 0 if OK. This procedure is already prototyped in crypto.h.

Note: the current generic code only calls this function with e and n (public key parameters): unless used internally by the backend, it is not needed to support the private key and the other parameters here.

int ssh2_rsa_new_priv(ssh2_rsa_ctx **rsa,
                      LIBSSH2_SESSION *session,
                      const char *filename,
                      const char *blob, size_t blob_len,
                      const char *passphrase);

Reads an RSA private key from file filename, or blob into a new RSA context. Must call ssh2_init_if_needed(). Return 0 if OK, else -1. This procedure is already prototyped in crypto.h.

int ssh2_rsa_sha1_verify(ssh2_rsa_ctx *rsa,
                         const unsigned char *sig,
                         size_t sig_len,
                         const unsigned char *m, size_t m_len);

Verify (sig, sig_len) signature of (m, m_len) using an SHA-1 hash and the RSA context. Return 0 if OK, else -1. This procedure is already prototyped in crypto.h.

int ssh2_rsa_sha1_signv(ssh2_rsa_ctx *rsa, LIBSSH2_SESSION *session,
                        unsigned char **sig, size_t *siglen,
                        int count, const struct iovec vector[]);

RSA signs the SHA-1 hash computed over the count data chunks in vector. Signature is stored at (sig, siglen). Signature buffer must be allocated from the given session. Returns 0 if OK, else -1. Note: this procedure is optional: if provided, it MUST be defined as a macro.

int ssh2_rsa_sha1_sign(ssh2_rsa_ctx *rsa,
                       LIBSSH2_SESSION *session,
                       const unsigned char *hash, size_t hash_len,
                       unsigned char **signature, size_t *signature_len);

RSA signs the (hash, hashlen) SHA-1 hash bytes and stores the allocated signature at (signature, signature_len). Signature buffer must be allocated from the given session. Returns 0 if OK, else -1. This procedure is already prototyped in crypto.h. Note: this procedure is not used if macro ssh2_rsa_sha1_signv() is defined.

void ssh2_rsa_free(ssh2_rsa_ctx *rsa);

Releases the RSA computation context at rsa.

LIBSSH2_RSA_SHA2 define as 1 if the crypto library supports RSA SHA2 256/512, else 0. If defined as 0, the rest of this section can be omitted.

int ssh2_rsa_sha2_sign(ssh2_rsa_ctx *rsa,
                       LIBSSH2_SESSION *session,
                       const unsigned char *hash, size_t hash_len,
                       unsigned char **signature, size_t *signature_len);

RSA signs the (hash, hashlen) SHA-2 hash bytes based on hash length and stores the allocated signature at (signature, signature_len). Signature buffer must be allocated from the given session. Returns 0 if OK, else -1. This procedure is already prototyped in crypto.h. Note: this procedure is not used if both macros ssh2_rsa_sha2_256_signv() and ssh2_rsa_sha2_512_signv() are defined.

int ssh2_rsa_sha2_256_signv(ssh2_rsa_ctx *rsa, LIBSSH2_SESSION *session,
                            unsigned char **sig, size_t *siglen,
                            int count, const struct iovec vector[]);

RSA signs the SHA-256 hash computed over the count data chunks in vector. Signature is stored at (sig, siglen). Signature buffer must be allocated from the given session. Returns 0 if OK, else -1. Note: this procedure is optional: if provided, it MUST be defined as a macro.

int ssh2_rsa_sha2_512_signv(ssh2_rsa_ctx *rsa, LIBSSH2_SESSION *session,
                            unsigned char **sig, size_t *siglen,
                            int count, const struct iovec vector[]);

RSA signs the SHA-512 hash computed over the count data chunks in vector. Signature is stored at (sig, siglen). Signature buffer must be allocated from the given session. Returns 0 if OK, else -1. Note: this procedure is optional: if provided, it MUST be defined as a macro.

int ssh2_rsa_sha2_verify(ssh2_rsa_ctx *rsa,
                         size_t hash_len,
                         const unsigned char *sig, size_t sig_len,
                         const unsigned char *m, size_t m_len);

Verify (sig, sig_len) signature of (m, m_len) using an SHA-2 hash based on hash length and the RSA context. Return 0 if OK, else -1. This procedure is already prototyped in crypto.h.

7.2) DSA

LIBSSH2_DSA: define as 1 if the crypto library supports DSA, else 0. If defined as 0, the rest of this section can be omitted.

ssh2_dsa_ctx: Type of a DSA computation context. Generally a struct.

int ssh2_dsa_new(ssh2_dsa_ctx **dsa,
                 const unsigned char *pdata, size_t plen,
                 const unsigned char *qdata, size_t qlen,
                 const unsigned char *gdata, size_t glen,
                 const unsigned char *ydata, size_t ylen,
                 const unsigned char *x, size_t x_len);

Creates a new context for DSA computations from source key values:

  • pdata, plen Prime number p. Only used if private key known (ddata).
  • qdata, qlen Prime number q. Only used if private key known (ddata).
  • gdata, glen G number.
  • ydata, ylen Public key.
  • xdata, xlen Private key. Only taken if xlen non-zero.

Returns 0 if OK. This procedure is already prototyped in crypto.h.

int ssh2_dsa_new_priv(ssh2_dsa_ctx **dsa,
                      LIBSSH2_SESSION *session,
                      const char *filename,
                      const char *blob, size_t blob_len,
                      const char *passphrase);

Reads a DSA private key from file filename, or blob into a new DSA context. Must call ssh2_init_if_needed(). Returns 0 if OK, else -1. This procedure is already prototyped in crypto.h.

int ssh2_dsa_sha1_verify(ssh2_dsa_ctx *dsa,
                         const unsigned char *sig,
                         const unsigned char *m, size_t m_len);

Verify (sig, siglen) signature of (m, m_len) using an SHA-1 hash and the DSA context. Returns 0 if OK, else -1. This procedure is already prototyped in crypto.h.

int ssh2_dsa_sha1_sign(ssh2_dsa_ctx *dsa,
                       const unsigned char *hash,
                       size_t hash_len, unsigned char *sig);

DSA signs the (hash, hash_len) data using SHA-1 and store the signature at sig. Returns 0 if OK, else -1. This procedure is already prototyped in crypto.h.

void ssh2_dsa_free(ssh2_dsa_ctx *dsa);

Releases the DSA computation context at dsa.

7.3) ECDSA

LIBSSH2_ECDSA: define as 1 if the crypto library supports ECDSA, else 0. If defined as 0, ssh2_ec_key should be defined as void and the rest of this section can be omitted.

ssh2_ecdsa_ctx: Type of an ECDSA computation context. Generally a struct.

ssh2_ec_key: Type of an elliptic curve key.

ssh2_curve_type: An enum type defining curve types. Current supported identifiers are:

  • SSH2_EC_CURVE_NISTP256
  • SSH2_EC_CURVE_NISTP384
  • SSH2_EC_CURVE_NISTP521
int ssh2_ecdsa_create_key(ssh2_ec_key **ec_ctx, LIBSSH2_SESSION *session,
                          unsigned char **out_public_key_octal,
                          size_t *out_public_key_octal_len,
                          ssh2_curve_type curve);

Create a new ECDSA private key of type curve and return it at ec_ctx. If out_public_key_octal is not NULL, store an allocated pointer to the associated public key in "octal" form in it and its length at out_public_key_octal_len. Return 0 if OK, else -1. This procedure is already prototyped in crypto.h.

int ssh2_ecdsa_new_priv(ssh2_ecdsa_ctx **ec_ctx,
                        LIBSSH2_SESSION *session,
                        const char *filename,
                        const char *blob, size_t blob_len,
                        const char *passphrase);

Reads an ECDSA private key from file filename, or blob into a new ECDSA context stored at ec_ctx. Must call ssh2_init_if_needed(). Return 0 if OK, else -1. This procedure is already prototyped in crypto.h.

int ssh2_ecdsa_curve_name_with_octal_new(ssh2_ecdsa_ctx **ec_ctx,
                                         const unsigned char *k,
                                         size_t k_len,
                                         ssh2_curve_type curve);

Stores at ec_ctx a new ECDSA context associated with the given curve type and with "octal" form public key (k, k_len). Return 0 if OK, else -1. This procedure is already prototyped in crypto.h.

int ssh2_ecdsa_new_openssh_private(ssh2_ecdsa_ctx **ec_ctx,
                                   LIBSSH2_SESSION *session,
                                   const char *filename,
                                   const char *passphrase);

Reads a PEM-encoded ECDSA private key from file filename encrypted with passphrase and stores at ec_ctx a new ECDSA context for it. Return 0 if OK, else -1. Currently used only from openssl backend (ought to be private). This procedure is already prototyped in crypto.h.

int ssh2_ecdsa_sign(ssh2_ecdsa_ctx *ec_ctx, LIBSSH2_SESSION *session,
                    const unsigned char *hash, size_t hash_len,
                    unsigned char **signature, size_t *signature_len);

ECDSA signs the (hash, hashlen) hash bytes and stores the allocated signature at (signature, signature_len). Hash algorithm used should be SHA-256, SHA-384 or SHA-512 depending on type stored in ECDSA context at ec_ctx. Signature buffer must be allocated from the given session. Returns 0 if OK, else -1. This procedure is already prototyped in crypto.h.

int ssh2_ecdsa_verify(ssh2_ecdsa_ctx *ec_ctx,
                      const unsigned char *r, size_t r_len,
                      const unsigned char *s, size_t s_len,
                      const unsigned char *m, size_t m_len);

Verify the ECDSA signature made of (r, r_len) and (s, s_len) of (m, m_len) using the hash algorithm configured in the ECDSA context ec_ctx. Return 0 if OK, else -1. This procedure is already prototyped in crypto.h.

ssh2_curve_type ssh2_ecdsa_get_curve_type(ssh2_ecdsa_ctx *ec_ctx);

Returns the curve type associated with given context. This procedure is already prototyped in crypto.h.

void ssh2_ecdsa_free(ssh2_ecdsa_ctx *ec_ctx);

Releases the ECDSA computation context at ec_ctx.

7.4) ED25519

LIBSSH2_ED25519: define as 1 if the crypto library supports ED25519, else 0. If defined as 0, the rest of this section can be omitted.

ssh2_ed25519_ctx Type of an ED25519 computation context. Generally a struct.

int ssh2_curve25519_new(LIBSSH2_SESSION *session,
                        uint8_t **out_public_key,
                        uint8_t **out_private_key);

Generates an ED25519 key pair, stores a pointer to them at out_private_key and out_public_key respectively and stores at ctx a new ED25519 context for this key. Argument ctx, out_private_key and out_public key may be NULL to disable storing the corresponding value. Length of each key is SSH2_ED25519_KEY_LEN (32 bytes). Key buffers are allocated and should be released by caller after use. Returns 0 if OK, else -1. This procedure is already prototyped in crypto.h.

int ssh2_ed25519_new_public(ssh2_ed25519_ctx **ed_ctx,
                            LIBSSH2_SESSION *session,
                            const unsigned char *raw_pub_key,
                            const size_t key_len);

Stores at ed_ctx a new ED25519 key context for raw public key (raw_pub_key, key_len). Return 0 if OK, else -1. This procedure is already prototyped in crypto.h.

int ssh2_ed25519_new_priv(ssh2_ed25519_ctx **ed_ctx,
                          LIBSSH2_SESSION *session,
                          const char *filename,
                          const char *blob, size_t blob_len,
                          const char *passphrase);

Reads an ED25519 private key from file filename, or blob into a new ED25519 context stored at ed_ctx. Must call ssh2_init_if_needed(). Return 0 if OK, else -1. This procedure is already prototyped in crypto.h.

int ssh2_ed25519_sign(ssh2_ed25519_ctx *ed_ctx, LIBSSH2_SESSION *session,
                      uint8_t **out_sig, size_t *out_sig_len,
                      const uint8_t *message, size_t message_len);

ED25519 signs the (message, message_len) bytes and stores the allocated signature at (sig, sig_len). Signature buffer is allocated from the given session. Returns 0 if OK, else -1. This procedure is already prototyped in crypto.h.

int ssh2_ed25519_verify(ssh2_ed25519_ctx *ed_ctx, LIBSSH2_SESSION *session,
                        const uint8_t *s, size_t s_len,
                        const uint8_t *m, size_t m_len);

Verify (s, s_len) signature of (m, m_len) using the given ED25519 context. Return 0 if OK, else -1. This procedure is already prototyped in crypto.h.

int ssh2_curve25519_gen_k(ssh2_bn **k,
                          uint8_t private_key[SSH2_ED25519_KEY_LEN],
                          uint8_t srvr_public_key[SSH2_ED25519_KEY_LEN]);

Computes a shared ED25519 secret key from the given raw server public key and raw client public key and stores it as a big number in *k. Big number should have been initialized before calling this function. Returns 0 if OK, else -1. This procedure is already prototyped in crypto.h.

void ssh2_ed25519_free(ssh2_ed25519_ctx *ed_ctx);

Releases the ED25519 computation context at ed_ctx.

8) Miscellaneous

void ssh2_prepare_iovec(struct iovec *vector, unsigned int len);

Prepare len consecutive iovec slots before using them. In example, this is needed to preset unused structure slacks on platforms requiring it. If this is not needed, it should be defined as an empty macro.

int ssh2_random(unsigned char *buf, size_t len);

Store len random bytes at buf. Returns 0 if OK, else -1.