Aller au contenu principal

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 hachage
  • SHA$$$HashSizeBits - nombre de bits dans le hachage
  • SHA$$$_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ès
  • shaNull(1) - lorsqu'un paramètre de pointeur null est présenté
  • shaInputTooLong(2) - lorsque les données d'entrée sont trop longues
  • shaStateError(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és
  • USAMaxHashSize - maximum des tailles de hachage SHA
  • SHA$$$ - 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)​