[GMSSL] Analyse et solution de BUG dans la fonction i2o_SM2CiphertextValue

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 cl'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_SM2CiphertextValuemodifie 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_SM2CiphertextValueBloquez simplement le code suivant :

/* output */
if (*pout) {
    
    
	//*pout = p;
} else {
    
    
	*pout = buf;
	buf = NULL;
}

おすすめ

転載: blog.csdn.net/KXue0703/article/details/129079586