/*!========================================================================
  @ingroup      Sec
  @file         RTESec_SCRAMMD5.h
  @author       ChristophB

  @brief

  @since        2004-08-18  16:34
  @sa

  ==========================================================================

    The following sample source code implements SCRAM itself for both
    server and client.

    Please note the lines marked "XXX: ..." as they need to be
    translated from English to computer readable code.

    A client implementation simply calls scram_md5_generate() with the
    passphrase after receiving the first server reply.  The cproof
    parameter will hold the message to send to the server and the
    sproof parameter will hold the expected server mutual
    authentication.  The clidata parameter holds the client's security
    layer selections.  A client may also call hmac_md5_precalc() to
    turn a passphrase into CRAM/SCRAM credentials for later use in
    scram_md5_generate().

    A server implementation simply calls scram_md5_generate() with the
    stored verifier, the second client message and the SCRAM_VERIFY
    option.  Server verifiers are generated by creating a random salt
    and calling SCRAMMD5GenVerifier() with either the passphrase or
    CRAM/SCRAM credentials.

    If integrity protection is desired, the integrity_key parameter may
    be provided to scram_md5_generate() and will receive the resulting
    key. Generating an verifying the integrity protection is left as
    an exercise to the reader.
 ============================================================================*/

#ifndef RTESEC_SCRAM_MD5_H
#define RTESEC_SCRAM_MD5_H RTESEC_SCRAM_MD5_H

/*===========================================================================*
 *  INCLUDES                                                               *
 *===========================================================================*/
#include "gsp01.h"
#include "RunTime/RTE_Types.h"

/*===========================================================================*
 *  DEFINES                                                                   *
 *===========================================================================*/
/* size of SCRAM_MD5 salt and verifier */
#define SCRAMMD5_SALTSIZE 8
#define SCRAMMD5_DATASIZE 16

/* scram secret action type */
#define SCRAM_CREDENTIAL 0 /* generate replies using credentials */
#define SCRAM_PLAINTEXT  1 /* generate replies using plaintext */
#define SCRAM_VERIFY     2 /* use SCRAMMD5_VRFY to verify client,
                              and generate server reply */

/*===========================================================================*
 *  LOCAL CLASSES, STRUCTURES, TYPES, UNIONS ...                             *
 *===========================================================================*/
/*! SCRAM verifier */
typedef struct SCRAMMD5_VRFY_s {
    unsigned char salt[SCRAMMD5_SALTSIZE];
    unsigned char clidata[SCRAMMD5_DATASIZE];
    unsigned char svrdata[SCRAMMD5_DATASIZE];
} SCRAMMD5_VRFY;

/*! Client proof message */
typedef struct SCRAMMD5_CLIENT_s {
    unsigned char cproof[SCRAMMD5_DATASIZE];
} SCRAMMD5_CLIENT;

/*===========================================================================*
 *  PROTOTYPES                                                               *
 *===========================================================================*/

/*
 * generate SCRAM-MD5 verifier
 * vptr      -- gets result
 * salt      -- contains salt of SCRAMMD5_SALTSIZE
 * pass      -- passphrase or verifier
 * clientkey -- cache for client proof, usually NULL
 */
externC void SCRAMMD5GenVerifier (SCRAMMD5_VRFY *vptr,
                     const unsigned char *salt,
                     const char *pass, int pwdlen,
                     unsigned char *clientkey);

/*
 * generate or verify SCRAMMD5
 * output:
 * clidata       -- client data for client response
 * input params:
 * cchal         -- client challenge string
 * cchallen      -- length of client challenge
 * schal         -- server challenge string
 * schallen      -- length of server challenge
 * secret        -- passphrase, credentials, or verifier
 * secretlen     -- length of passphrase (0 ok if NUL terminated)
 * action        -- see above
 * in/out:
 * output:
 * sproof        -- server proof of length SCRAMMD5_DATASIZE
 * returns:
 * -2 if params invalid
 * -1 if verify fails
 *  0 on success
 */
externC int SCRAMMD5GenClient (
    SCRAMMD5_CLIENT *clidata,
    const char *cchal, int cchallen,
    const char *salt, int saltlen,
    const char *schal, int schallen,
    const char *password, int pwdlen,
    unsigned char *sproof);

externC int SCRAMMD5Gen (
    SCRAMMD5_CLIENT *clidata,
    const char *cchal, int cchallen,
    const char *salt, int saltlen,
    const char *schal, int schallen,
    const char *secret, int secretlen,
    int action,
    unsigned char *sproof);

#endif
