blob: dd49d75d56567be2c9e2873effcf2b3be3017f2e [file] [log] [blame]
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
/**
* @file mpin.h
* @author Mike Scott and Kealan McCusker
* @date 2nd June 2015
* @brief M-Pin Header file
*
* Allows some user configuration
* defines structures
* declares functions
*
*/
#ifndef MPIN_H
#define MPIN_H
#include "amcl.h"
/* Field size is assumed to be greater than or equal to group size */
#define PGS 32 /**< MPIN Group Size */
#define PFS 32 /**< MPIN Field Size */
#define PAS 16 /**< MPIN Symmetric Key Size */
#define MPIN_OK 0 /**< Function completed without error */
/*#define MPIN_DOMAIN_ERROR -11
#define MPIN_INVALID_PUBLIC_KEY -12
#define MPIN_ERROR -13*/
#define MPIN_INVALID_POINT -14 /**< Point is NOT on the curve */
/*#define MPIN_DOMAIN_NOT_FOUND -15
#define MPIN_OUT_OF_MEMORY -16
#define MPIN_DIV_BY_ZERO -17
#define MPIN_WRONG_ORDER -18*/
#define MPIN_BAD_PIN -19 /**< Bad PIN number entered */
/* Configure your PIN here */
#define MAXPIN 10000 /**< max PIN */
#define PBLEN 14 /**< max length of PIN in bits */
#define TIME_SLOT_MINUTES 1440 /**< Time Slot = 1 day */
#define HASH_BYTES 32 /**< Number of bytes output by Hash function */
/* MPIN support functions */
/* MPIN primitives */
/** @brief Hash an M-Pin Identity to an octet string
*
@param ID an octet containing the identity
@param HID an octet containing the hashed identity
*/
DLL_EXPORT void MPIN_HASH_ID(octet *ID,octet *HID);
/** @brief Get epoch time as unsigned integer
*
@return current epoch time in seconds
*/
DLL_EXPORT unsign32 MPIN_GET_TIME(void);
/** @brief Generate Y=H(t,O), where t is epoch time, O is an octet, and H(.) is a hash function
*
@param t is epoch time in seconds
@param O is an input octet
@param Y is the output octet
*/
DLL_EXPORT void MPIN_GET_Y(int t,octet *O,octet *Y);
/** @brief Extract a PIN number from a client secret
*
@param ID is the input client identity
@param pin is an input PIN number
@param CS is the client secret from which the PIN is to be extracted
@return 0 or an error code
*/
DLL_EXPORT int MPIN_EXTRACT_PIN(octet *ID,int pin,octet *CS);
/** @brief Perform client side of the one-pass version of the M-Pin protocol
*
If Time Permits are disabled, set d = 0, and UT is not generated and can be set to NULL.
If Time Permits are enabled, and PIN error detection is OFF, U is not generated and can be set to NULL.
If Time Permits are enabled, and PIN error detection is ON, U and UT are both generated.
@param d is input date, in days since the epoch. Set to 0 if Time permits disabled
@param ID is the input client identity
@param R is a pointer to a cryptographically secure random number generator
@param x an output internally randomly generated if R!=NULL, otherwise must be provided as an input
@param pin is the input PIN number
@param T is the input M-Pin token (the client secret with PIN portion removed)
@param V is output = -(x+y)(CS+TP), where CS is the reconstructed client secret, and TP is the time permit
@param U is output = x.H(ID)
@param UT is output = x.(H(ID)+H(d|H(ID)))
@param TP is the input time permit
@param MESSAGE is the message to be signed
@param t is input epoch time in seconds - a timestamp
@param y is output H(t|U) or H(t|UT) if Time Permits enabled
@return 0 or an error code
*/
DLL_EXPORT int MPIN_CLIENT(int d,octet *ID,csprng *R,octet *x,int pin,octet *T,octet *V,octet *U,octet *UT,octet *TP, octet* MESSAGE, int t, octet *y);
/** @brief Perform first pass of the client side of the 3-pass version of the M-Pin protocol
*
If Time Permits are disabled, set d = 0, and UT is not generated and can be set to NULL.
If Time Permits are enabled, and PIN error detection is OFF, U is not generated and can be set to NULL.
If Time Permits are enabled, and PIN error detection is ON, U and UT are both generated.
@param d is input date, in days since the epoch. Set to 0 if Time permits disabled
@param ID is the input client identity
@param R is a pointer to a cryptographically secure random number generator
@param x an output internally randomly generated if R!=NULL, otherwise must be provided as an input
@param pin is the input PIN number
@param T is the input M-Pin token (the client secret with PIN portion removed)
@param S is output = CS+TP, where CS=is the reconstructed client secret, and TP is the time permit
@param U is output = x.H(ID)
@param UT is output = x.(H(ID)+H(d|H(ID)))
@param TP is the input time permit
@return 0 or an error code
*/
DLL_EXPORT int MPIN_CLIENT_1(int d,octet *ID,csprng *R,octet *x,int pin,octet *T,octet *S,octet *U,octet *UT,octet *TP);
/** @brief Generate a random group element
*
@param R is a pointer to a cryptographically secure random number generator
@param S is the output random octet
@return 0 or an error code
*/
DLL_EXPORT int MPIN_RANDOM_GENERATE(csprng *R,octet *S);
/** @brief Perform second pass of the client side of the 3-pass version of the M-Pin protocol
*
@param x an input, a locally generated random number
@param y an input random challenge from the server
@param V on output = -(x+y).V
@return 0 or an error code
*/
DLL_EXPORT int MPIN_CLIENT_2(octet *x,octet *y,octet *V);
/** @brief Perform server side of the one-pass version of the M-Pin protocol
*
If Time Permits are disabled, set d = 0, and UT and HTID are not generated and can be set to NULL.
If Time Permits are enabled, and PIN error detection is OFF, U and HID are not needed and can be set to NULL.
If Time Permits are enabled, and PIN error detection is ON, U, UT, HID and HTID are all required.
@param d is input date, in days since the epoch. Set to 0 if Time permits disabled
@param HID is output H(ID), a hash of the client ID
@param HTID is output H(ID)+H(d|H(ID))
@param y is output H(t|U) or H(t|UT) if Time Permits enabled
@param SS is the input server secret
@param U is input from the client = x.H(ID)
@param UT is input from the client= x.(H(ID)+H(d|H(ID)))
@param V is an input from the client
@param E is an output to help the Kangaroos to find the PIN error, or NULL if not required
@param F is an output to help the Kangaroos to find the PIN error, or NULL if not required
@param ID is the input claimed client identity
@param MESSAGE is the message to be signed
@param t is input epoch time in seconds - a timestamp
@return 0 or an error code
*/
DLL_EXPORT int MPIN_SERVER(int d,octet *HID,octet *HTID,octet *y,octet *SS,octet *U,octet *UT,octet *V,octet *E,octet *F,octet *ID,octet *MESSAGE, int t);
/** @brief Perform first pass of the server side of the 3-pass version of the M-Pin protocol
*
@param d is input date, in days since the epoch. Set to 0 if Time permits disabled
@param ID is the input claimed client identity
@param HID is output H(ID), a hash of the client ID
@param HTID is output H(ID)+H(d|H(ID))
@return 0 or an error code
*/
DLL_EXPORT void MPIN_SERVER_1(int d,octet *ID,octet *HID,octet *HTID);
/** @brief Perform third pass on the server side of the 3-pass version of the M-Pin protocol
*
If Time Permits are disabled, set d = 0, and UT and HTID are not needed and can be set to NULL.
If Time Permits are enabled, and PIN error detection is OFF, U and HID are not needed and can be set to NULL.
If Time Permits are enabled, and PIN error detection is ON, U, UT, HID and HTID are all required.
@param d is input date, in days since the epoch. Set to 0 if Time permits disabled
@param HID is input H(ID), a hash of the client ID
@param HTID is input H(ID)+H(d|H(ID))
@param y is the input server's randomly generated challenge
@param SS is the input server secret
@param U is input from the client = x.H(ID)
@param UT is input from the client= x.(H(ID)+H(d|H(ID)))
@param V is an input from the client
@param E is an output to help the Kangaroos to find the PIN error, or NULL if not required
@param F is an output to help the Kangaroos to find the PIN error, or NULL if not required
@return 0 or an error code
*/
DLL_EXPORT int MPIN_SERVER_2(int d,octet *HID,octet *HTID,octet *y,octet *SS,octet *U,octet *UT,octet *V,octet *E,octet *F);
/** @brief Add two members from the group G1
*
@param Q1 an input member of G1
@param Q2 an input member of G1
@param Q an output member of G1 = Q1+Q2
@return 0 or an error code
*/
DLL_EXPORT int MPIN_RECOMBINE_G1(octet *Q1,octet *Q2,octet *Q);
/** @brief Add two members from the group G2
*
@param P1 an input member of G2
@param P2 an input member of G2
@param P an output member of G2 = P1+P2
@return 0 or an error code
*/
DLL_EXPORT int MPIN_RECOMBINE_G2(octet *P1,octet *P2,octet *P);
/** @brief Use Kangaroos to find PIN error
*
@param E a member of the group GT
@param F a member of the group GT = E^e
@return 0 if Kangaroos failed, or the PIN error e
*/
DLL_EXPORT int MPIN_KANGAROO(octet *E,octet *F);
/** @brief Encoding of a Time Permit to make it indistinguishable from a random string
*
@param R is a pointer to a cryptographically secure random number generator
@param TP is the input time permit, obfuscated on output
@return 0 or an error code
*/
DLL_EXPORT int MPIN_ENCODING(csprng *R,octet *TP);
/** @brief Encoding of an obfuscated Time Permit
*
@param TP is the input obfuscated time permit, restored on output
@return 0 or an error code
*/
DLL_EXPORT int MPIN_DECODING(octet *TP);
/** @brief Supply today's date as days from the epoch
*
@return today's date, as number of days elapsed since the epoch
*/
DLL_EXPORT unsign32 MPIN_today(void);
/** @brief Initialise a random number generator
*
@param R is a pointer to a cryptographically secure random number generator
@param S is an input truly random seed value
*/
DLL_EXPORT void MPIN_CREATE_CSPRNG(csprng *R,octet *S);
/** @brief Kill a random number generator
*
Deletes all internal state
@param R is a pointer to a cryptographically secure random number generator
*/
DLL_EXPORT void MPIN_KILL_CSPRNG(csprng *R);
/** @brief Find a random multiple of a point in G1
*
@param R is a pointer to a cryptographically secure random number generator
@param type determines type of action to be taken
@param x an output internally randomly generated if R!=NULL, otherwise must be provided as an input
@param G if type=0 a point in G1, else an octet to be mapped to G1
@param W the output =x.G or x.M(G), where M(.) is a mapping
@return 0 or an error code
*/
DLL_EXPORT int MPIN_GET_G1_MULTIPLE(csprng *R,int type,octet *x,octet *G,octet *W);
/** @brief Create a client secret in G1 from a master secret and the client ID
*
@param S is an input master secret
@param ID is the input client identity
@param CS is the full client secret = s.H(ID)
@return 0 or an error code
*/
DLL_EXPORT int MPIN_GET_CLIENT_SECRET(octet *S,octet *ID,octet *CS);
/** @brief Create a Time Permit in G1 from a master secret and the client ID
*
@param d is input date, in days since the epoch.
@param S is an input master secret
@param ID is the input client identity
@param TP is a Time Permit for the given date = s.H(d|H(ID))
@return 0 or an error code
*/
DLL_EXPORT int MPIN_GET_CLIENT_PERMIT(int d,octet *S,octet *ID,octet *TP);
/** @brief Create a server secret in G2 from a master secret
*
@param S is an input master secret
@param SS is the server secret = s.Q where Q is a fixed generator of G2
@return 0 or an error code
*/
DLL_EXPORT int MPIN_GET_SERVER_SECRET(octet *S,octet *SS);
/* DLL_EXPORT int MPIN_TEST_PAIRING(octet *,octet *); */
/* For M-Pin Full */
/** @brief Precompute values for use by the client side of M-Pin Full
*
@param T is the input M-Pin token (the client secret with PIN portion removed)
@param ID is the input client identity
@param g1 precomputed output
@param g2 precomputed output
@return 0 or an error code
*/
DLL_EXPORT int MPIN_PRECOMPUTE(octet *T,octet *ID,octet *g1,octet *g2);
/** @brief Calculate Key on Server side for M-Pin Full
*
Uses UT internally for the key calculation, unless not available in which case U is used
@param Z is the input Client-side Diffie-Hellman component
@param SS is the input server secret
@param w is an input random number generated by the server
@param p is an input, hash of the protocol transcript
@param I is the hashed input client ID = H(ID)
@param U is input from the client = x.H(ID)
@param UT is input from the client= x.(H(ID)+H(d|H(ID)))
@param K is the output calculated shared key
@return 0 or an error code
*/
DLL_EXPORT int MPIN_SERVER_KEY(octet *Z,octet *SS,octet *w,octet *p,octet *I,octet *U,octet *UT,octet *K);
/** @brief Calculate Key on Client side for M-Pin Full
*
@param g1 precomputed input
@param g2 precomputed input
@param pin is the input PIN number
@param r is an input, a locally generated random number
@param x is an input, a locally generated random number
@param p is an input, hash of the protocol transcript
@param T is the input Server-side Diffie-Hellman component
@param K is the output calculated shared key
@return 0 or an error code
*/
DLL_EXPORT int MPIN_CLIENT_KEY(octet *g1,octet *g2,int pin,octet *r,octet *x,octet *p,octet *T,octet *K);
/** @brief AES-GCM Encryption
*
@param K AES key
@param IV Initialization vector
@param H Header
@param P Plaintext
@param C Ciphertext
@param T Checksum
*/
DLL_EXPORT void MPIN_AES_GCM_ENCRYPT(octet *K,octet *IV,octet *H,octet *P,octet *C,octet *T);
/** @brief AES-GCM Decryption
*
@param K AES key
@param IV Initialization vector
@param H Header
@param P Plaintext
@param C Ciphertext
@param T Checksum
*/
DLL_EXPORT void MPIN_AES_GCM_DECRYPT(octet *K,octet *IV,octet *H,octet *C,octet *P,octet *T);
/** @brief HMAC of message M using key K to create tag of length len in octet tag
*
IEEE-1363 MAC1 function. Uses SHA256 internally.
@param M input message octet
@param K input encryption key
@param len is output desired length of HMAC tag
@param tag is the output HMAC
@return 0 for bad parameters, else 1
*/
DLL_EXPORT int MPIN_HMAC(octet *M,octet *K,int len,octet *tag);
/** @brief Password Based Key Derivation Function - generates key K from password, salt and repeat counter
*
PBKDF2 Password Based Key Derivation Function. Uses SHA256 internally.
@param P input password
@param S input salt
@param rep Number of times to be iterated.
@param len is output desired length of key
@param K is the derived key
*/
DLL_EXPORT void MPIN_PBKDF2(octet *P,octet *S,int rep,int len,octet *K);
/** @brief Hash the session transcript
@param I is the hashed input client ID = H(ID)
@param U is the client output = x.H(ID)
@param CU is the client output = x.(H(ID)+H(T|H(ID)))
@param Y is the server challenge
@param V is the client part response
@param R is the client part response
@param W is the server part response
@param H the output is the hash of all of the above that apply
*/
DLL_EXPORT void MPIN_HASH_ALL(octet *I,octet *U,octet *CU,octet *V,octet *Y,octet *R,octet *W,octet *H);
#endif