8. C Code for SHAs, HMAC, and HKDF (Code C pour SHA, HMAC et HKDF)
Ci-dessous se trouve une implémentation de démonstration de ces fonctions de hachage sécurisées en C. La section 8.1 contient le fichier d'en-tête sha.h qui déclare toutes les constantes, structures et fonctions utilisées par les fonctions SHA et HMAC. Il inclut des conditions basées sur l'état de définition de USE_32BIT_ONLY qui, si ce symbole est défini au moment de la compilation, évite les opérations 64 bits. Il contient également sha-private.h qui fournit certaines déclarations communes à toutes les fonctions SHA. La section 8.2 contient le code C pour sha1.c, sha224-256.c, sha384-512.c et usha.c. La section 8.3 contient le code C pour les fonctions HMAC, et la section 8.4 contient le code C pour HKDF. La section 8.5 contient un pilote de test pour exercer le code.
Aperçu de l'API (API Overview)
Pour chacune des longueurs de condensé $$$, il existe l'ensemble suivant de constantes, une structure et des fonctions :
Constantes (Constants):
SHA$$$HashSize- nombre d'octets dans le hachageSHA$$$HashSizeBits- nombre de bits dans le hachageSHA$$$_Message_Block_Size- nombre d'octets utilisés dans les blocs de message intermédiaires
La plupart des fonctions retournent une valeur d'énumération qui est l'une des suivantes :
shaSuccess(0)- en cas de succèsshaNull(1)- lorsqu'un paramètre de pointeur null est présentéshaInputTooLong(2)- lorsque les données d'entrée sont trop longuesshaStateError(3)- lorsque SHA$$$Input est appelé après SHA$$$FinalBits ou SHA$$$Result
Structure:
typedef SHA$$$Context
Une structure opaque contenant l'état complet pour produire le hachage
Fonctions (Functions):
int SHA$$$Reset(SHA$$$Context *context);
Réinitialiser l'état du contexte de hachage.
int SHA$$$Input(SHA$$$Context *context, const uint8_t *octets,
unsigned int bytecount);
Incorporer bytecount octets dans le hachage.
int SHA$$$FinalBits(SHA$$$Context *, const uint8_t octet,
unsigned int bitcount);
Incorporer bitcount bits dans le hachage. Les bits sont dans la partie supérieure de l'octet. SHA$$$Input() ne peut pas être appelé après cela.
int SHA$$$Result(SHA$$$Context *,
uint8_t Message_Digest[SHA$$$HashSize]);
Effectuer les calculs finaux sur le hachage et copier la valeur dans Message_Digest.
Interface USHA (USHA Interface)
De plus, des fonctions avec le préfixe USHA sont fournies qui prennent une valeur SHAversion (SHA$$$) pour sélectionner la suite de fonctions SHA. Elles ajoutent les constantes, structure et fonctions suivantes :
Constantes (Constants):
shaBadParam(4)- constante renvoyée par les fonctions USHA lorsqu'un mauvais paramètre SHAversion (SHA$$$) ou d'autres valeurs de paramètres illégales sont présentésUSAMaxHashSize- maximum des tailles de hachage SHASHA$$$- valeurs d'énumération SHAversion, utilisées par les fonctions USHA, HMAC et HKDF pour sélectionner la suite de fonctions SHA
Structure:
typedef USHAContext
Une structure opaque contenant l'état complet pour produire le hachage
Fonctions (Functions):
int USHAReset(USHAContext *context, SHAversion whichSha);
Réinitialiser l'état du contexte de hachage.
int USHAInput(USHAContext context*,
const uint8_t *bytes, unsigned int bytecount);
Incorporer bytecount octets dans le hachage.
int USHAFinalBits(USHAContext *context,
const uint8_t bits, unsigned int bitcount);
Incorporer bitcount bits dans le hachage.
int USHAResult(USHAContext *context,
uint8_t Message_Digest[USHAMaxHashSize]);
Effectuer les calculs finaux sur le hachage et copier la valeur dans Message_Digest. Les octets dans Message_Digest au-delà de USHAHashSize(whichSha) sont laissés intacts.
int USHAHashSize(enum SHAversion whichSha);
Le nombre d'octets dans le hachage donné.
int USHAHashSizeBits(enum SHAversion whichSha);
Le nombre de bits dans le hachage donné.
int USHABlockSize(enum SHAversion whichSha);
La taille de bloc interne pour le hachage donné.
const char *USHAHashName(enum SHAversion whichSha);
Cette fonction renverra le nom de l'algorithme SHA donné sous forme de chaîne.
Interface HMAC (HMAC Interface)
Les fonctions HMAC suivent le même modèle pour permettre l'utilisation de toute longueur d'entrée de texte.
Structure:
typedef HMACContext
Une structure opaque contenant l'état complet pour produire le condensé de message avec clé (MAC)
Fonctions (Functions):
int hmacReset(HMACContext *ctx, enum SHAversion whichSha,
const unsigned char *key, int key_len);
Réinitialiser l'état du contexte MAC.
int hmacInput(HMACContext *ctx, const unsigned char *text,
int text_len);
Incorporer text_len octets dans le MAC.
int hmacFinalBits(HMACContext *ctx, const uint8_t bits,
unsigned int bitcount);
Incorporer bitcount bits dans le MAC.
int hmacResult(HMACContext *ctx,
uint8_t Message_Digest[USHAMaxHashSize]);
Effectuer les calculs finaux sur le MAC et copier la valeur dans Message_Digest.
De plus, des interfaces combinées sont fournies, similaires à celles montrées dans [RFC2104], qui permettent l'utilisation d'une entrée de texte de longueur fixe :
int hmac(SHAversion whichSha,
const unsigned char *text, int text_len,
const unsigned char *key, int key_len,
uint8_t digest[USHAMaxHashSize])
Cette interface combinée effectue le calcul HMAC complet. Les variables sont les mêmes que dans les appels séparés ci-dessus.
Interface HKDF (HKDF Interface)
Les fonctions HKDF sont structurées de manière similaire aux fonctions HMAC.
Structure:
typedef HKDFContext
Une structure opaque contenant l'état complet pour effectuer la dérivation de clé HKDF d'extraction et d'expansion
Fonctions (Functions):
int hkdfReset(HKDFContext *context, enum SHAversion whichSha,
const unsigned char *salt, int salt_len);
Réinitialiser l'état du contexte HKDF.
int hkdfInput(HKDFContext *context, const unsigned char *ikm,
int ikm_len);
Incorporer ikm_len octets dans l'extracteur d'entropie.
int hkdfFinalBits(HKDFContext *context, uint8_t ikm_bits,
unsigned int ikm_bit_count)
Incorporer ikm_bit_count bits dans l'extracteur d'entropie.
int hkdfResult(HKDFContext *context,
uint8_t prk[USHAMaxHashSize],
const unsigned char *info, int info_len,
uint8_t okm[ ], int okm_len)
Terminer l'extraction HKDF et effectuer l'expansion HKDF finale, en stockant les okm_len octets dans le matériel de clé de sortie (okm). Stocker éventuellement la clé pseudo-aléatoire (prk) générée en interne.
De plus, des interfaces combinées sont fournies, similaires à celles montrées dans [RFC5869], qui permettent l'utilisation d'une entrée de texte de longueur fixe :
int hkdfExtract(SHAversion whichSha,
const unsigned char *salt, int salt_len,
const unsigned char *ikm, int ikm_len,
uint8_t prk[USHAMaxHashSize])
Effectuer l'extraction HKDF, en combinant les salt_len octets du sel facultatif avec les ikm_len octets du matériel de clé d'entrée (ikm) pour former la clé pseudo-aléatoire prk. La sortie prk doit être suffisamment grande pour contenir les octets appropriés pour le type de hachage donné.
int hkdfExpand(SHAversion whichSha,
const uint8_t prk[ ], int prk_len,
const unsigned char *info, int info_len,
uint8_t okm[ ], int okm_len)
Effectuer l'expansion HKDF, en combinant les prk_len octets de la clé pseudo-aléatoire prk avec les info_len octets d'info pour former les okm_len octets stockés dans okm.
int hkdf(SHAversion whichSha,
const unsigned char *salt, int salt_len,
const unsigned char *ikm, int ikm_len,
const unsigned char *info, int info_len,
uint8_t okm[ ], int okm_len)
Cette interface combinée effectue à la fois l'extraction et l'expansion HKDF. Les variables sont les mêmes que dans hkdfExtract() et hkdfExpand().
Sous-sections (Subsections)
- 8.1. The Header Files (Fichiers d'en-tête)
- 8.1.1. sha.h
- 8.1.2. stdint-example.h
- 8.1.3. sha-private.h
- 8.2. The SHA Code (Code SHA)
- 8.2.1. sha1.c
- 8.2.2. sha224-256.c
- 8.2.3. sha384-512.c
- 8.2.4. usha.c
- 8.3. The HMAC Code (Code HMAC)
- 8.4. The HKDF Code (Code HKDF)
- 8.5. The Test Driver (Pilote de test)