1. Écrivez devant
Récemment, des collègues qui ont besoin d'aider le circuit intégré matériel pour vérifier le cryptage, le décryptage, la signature, la vérification de signature, l'échange de clé secrète et d'autres fonctions de SM2. Pour cette raison, nous utilisons l'algorithme logiciel de GMSSL comme référence pour vérifier l'implémentation matérielle d'IC, mais lors de la vérification du cryptage SM2, nous avons trouvé un bogue dans i2o_SM2CiphertextValue, comme suit :
2. Description du problème
Ce qui suit est une interface de fonction écrite par moi pour appeler l'interface GMSSL afin d'implémenter le cryptage SM2. Au cours du test, il s'avère que les données de sortie dans le pointeur *c ne sont pas ce que nous voulons. Après impression de l'adresse, on constate que l'adresse du pointeur c a changé avant et après c
l'appel de la fonction .i2o_SM2CiphertextValue
uint32_t Simu_Sm2_Encrypt(uint8_t *m, uint32_t mLen,
uint8_t *rand_key, uint8_t *pubkey,
uint8_t *c, uint32_t *cLen)
{
......
printf("Before c = %p\n", c); /* 测试,打印c的地址 */
if ((*cLen = i2o_SM2CiphertextValue(group, cv, &c)) <= 0)
{
printf("ERROR: %s %d\n", __func__, __LINE__);
goto ERR;
}
printf("After c = %p\n", c); /* 测试,打印c的地址 */
#if SIMU_DPI_SM2_DEBUG == 1
printf("Ciphertext[%d bytes] -->\n", *cLen);
BIO_dump_fp(stdout, (const char *)(c - *cLen), *cLen);
#endif
......
}
L'adresse du pointeur c imprimé après exécution est la suivante :
Avant c = 0x7ffdb2603520
Après c = 0x7ffdb26035a1
Alors il est certain que la fonction i2o_SM2CiphertextValue
modifie l'adresse du pointeur c. Après enquête, on constate que le problème est le code suivant :
int i2o_SM2CiphertextValue(const EC_GROUP *group, const SM2CiphertextValue *cv,
unsigned char **pout)
{
int ret = 0, outlen = 0, nbytes;
EC_POINT *point = NULL;
BN_CTX *bn_ctx = NULL;
unsigned char *buf;
unsigned char *p;
size_t siz;
......
if (*pout) {
p = *pout; // 若*pout非空,则使用外部传递的地址,存储数据,而我们传递的是c,所以非空
} else {
......
}
......
p += siz; // p指向的地址一直在增加
outlen += siz;
/* encode ciphertext */
memcpy(p, ASN1_STRING_get0_data(cv->ciphertext),
ASN1_STRING_length(cv->ciphertext));
p += ASN1_STRING_length(cv->ciphertext);
outlen += ASN1_STRING_length(cv->ciphertext);
/* encode hash */
memcpy(p, ASN1_STRING_get0_data(cv->hash),
ASN1_STRING_length(cv->hash));
p += ASN1_STRING_length(cv->hash); // p指向的地址一直在增加
outlen += ASN1_STRING_length(cv->hash);
/* output */
if (*pout) {
*pout = p; // 这里又将p的地址重新赋给了*pout,这是问题的关键所在
} else {
*pout = buf;
buf = NULL;
}
ret = outlen;
}
Après l'analyse du code ci-dessus, c'est la fonction qui modifie l'adresse du pointeur c, ce qui fait que le contenu pointé par c n'est pas ce que nous voulons.
3. Solutions
i2o_SM2CiphertextValue
Bloquez simplement le code suivant :
/* output */
if (*pout) {
//*pout = p;
} else {
*pout = buf;
buf = NULL;
}