crypto/asymmetric_keys/pkcs7_verify.c

Source file repositories/reference/linux-study-clean/crypto/asymmetric_keys/pkcs7_verify.c

File Facts

System
Linux kernel
Corpus path
crypto/asymmetric_keys/pkcs7_verify.c
Extension
.c
Size
14126 bytes
Lines
514
Domain
Kernel Services
Bucket
crypto
Inferred role
Kernel Services: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!sinfo->msgdigest) {
			pr_warn("Sig %u: No messageDigest\n", sinfo->index);
			ret = -EKEYREJECTED;
			goto error;
		}

		if (sinfo->msgdigest_len != sig->m_size) {
			pr_warn("Sig %u: Invalid digest size (%u)\n",
				sinfo->index, sinfo->msgdigest_len);
			ret = -EBADMSG;
			goto error;
		}

		if (memcmp(sig->m, sinfo->msgdigest,
			   sinfo->msgdigest_len) != 0) {
			pr_warn("Sig %u: Message digest doesn't match\n",
				sinfo->index);
			ret = -EKEYREJECTED;
			goto error;
		}

		/* We then calculate anew, using the authenticated attributes
		 * as the contents of the digest instead.  Note that we need to
		 * convert the attributes from a CONT.0 into a SET before we
		 * hash it.
		 *
		 * However, for certain algorithms, such as ML-DSA, the digest
		 * is integrated into the signing algorithm.  In such a case,
		 * we copy the authattrs, modifying the tag type, and set that
		 * as the digest.
		 */
		memcpy(sig->m, sinfo->authattrs, sinfo->authattrs_len);
		sig->m[0] = ASN1_CONS_BIT | ASN1_SET;

		if (sig->algo_takes_data) {
			sig->m_size = sinfo->authattrs_len;
			ret = 0;
		} else {
			ret = crypto_shash_digest(desc, sig->m,
						  sinfo->authattrs_len,
						  sig->m);
			if (ret < 0)
				goto error;
		}
		pr_devel("AADigest = [%*ph]\n", 8, sig->m);
	}

error:
	kfree(desc);
error_no_desc:
	crypto_free_shash(tfm);
	kleave(" = %d", ret);
	return ret;
}

int pkcs7_get_digest(struct pkcs7_message *pkcs7, const u8 **buf, u32 *len,
		     enum hash_algo *hash_algo)
{
	struct pkcs7_signed_info *sinfo = pkcs7->signed_infos;
	int i, ret;

	/*
	 * This function doesn't support messages with more than one signature.
	 */
	if (sinfo == NULL || sinfo->next != NULL)
		return -EBADMSG;

	ret = pkcs7_digest(pkcs7, sinfo);
	if (ret)
		return ret;
	if (!sinfo->sig->m_free) {
		pr_notice_once("%s: No digest available\n", __func__);
		return -EINVAL; /* TODO: MLDSA doesn't necessarily calculate an
				 * intermediate digest. */
	}

	*buf = sinfo->sig->m;
	*len = sinfo->sig->m_size;

	i = match_string(hash_algo_name, HASH_ALGO__LAST,
			 sinfo->sig->hash_algo);
	if (i >= 0)
		*hash_algo = i;

	return 0;
}

/*
 * Find the key (X.509 certificate) to use to verify a PKCS#7 message.  PKCS#7
 * uses the issuer's name and the issuing certificate serial number for

Annotation

Implementation Notes