- const EVP_MD *Hash, const EVP_MD *mgf1Hash,
- const unsigned char *EM, int sLen)
- {
- int i;
- int ret = 0;
- int hLen, maskedDBLen, MSBits, emLen;
- const unsigned char *H;
- unsigned char *DB = NULL;
- EVP_MD_CTX ctx;
- unsigned char H_[EVP_MAX_MD_SIZE];
- EVP_MD_CTX_init(&ctx);
-
- if (mgf1Hash == NULL)
- mgf1Hash = Hash;
-
- hLen = M_EVP_MD_size(Hash);
- if (hLen < 0)
- goto err;
- /*
- * Negative sLen has special meanings:
- * -1 sLen == hLen
- * -2 salt length is autorecovered from signature
- * -N reserved
- */
- if (sLen == -1) sLen = hLen;
- else if (sLen == -2) sLen = -2;
- else if (sLen < -2)
- {
- RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
- goto err;
- }
-
- MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
- emLen = RSA_size(rsa);
- if (EM[0] & (0xFF << MSBits))
- {
- RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_FIRST_OCTET_INVALID);
- goto err;
- }
- if (MSBits == 0)
- {
- EM++;
- emLen--;
- }
- if (emLen < (hLen + sLen + 2)) /* sLen can be small negative */
- {
- RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE);
- goto err;
- }
- if (EM[emLen - 1] != 0xbc)
- {
- RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_LAST_OCTET_INVALID);
- goto err;
- }
- maskedDBLen = emLen - hLen - 1;
- H = EM + maskedDBLen;
- DB = OPENSSL_malloc(maskedDBLen);
- if (!DB)
- {
- RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash) < 0)
- goto err;
- for (i = 0; i < maskedDBLen; i++)
- DB[i] ^= EM[i];
- if (MSBits)
- DB[0] &= 0xFF >> (8 - MSBits);
- for (i = 0; DB[i] == 0 && i < (maskedDBLen-1); i++) ;
- if (DB[i++] != 0x1)
- {
- RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_RECOVERY_FAILED);
- goto err;
- }
- if (sLen >= 0 && (maskedDBLen - i) != sLen)
- {
- RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
- goto err;
- }
- if (!EVP_DigestInit_ex(&ctx, Hash, NULL)
- || !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes)
- || !EVP_DigestUpdate(&ctx, mHash, hLen))
- goto err;
- if (maskedDBLen - i)
- {
- if (!EVP_DigestUpdate(&ctx, DB + i, maskedDBLen - i))
- goto err;
- }
- if (!EVP_DigestFinal_ex(&ctx, H_, NULL))
- goto err;
- if (memcmp(H_, H, hLen))
- {
- RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_BAD_SIGNATURE);
- ret = 0;
- }
- else
- ret = 1;
-
- err:
- if (DB)
- OPENSSL_free(DB);
- EVP_MD_CTX_cleanup(&ctx);
-
- return ret;
-
- }
+ const EVP_MD *Hash, const EVP_MD *mgf1Hash,
+ const unsigned char *EM, int sLen)
+{
+ int i;
+ int ret = 0;
+ int hLen, maskedDBLen, MSBits, emLen;
+ const unsigned char *H;
+ unsigned char *DB = NULL;
+ EVP_MD_CTX *ctx = EVP_MD_CTX_new();
+ unsigned char H_[EVP_MAX_MD_SIZE];
+
+ if (ctx == NULL)
+ goto err;
+
+ if (mgf1Hash == NULL)
+ mgf1Hash = Hash;
+
+ hLen = EVP_MD_size(Hash);
+ if (hLen < 0)
+ goto err;
+ /*-
+ * Negative sLen has special meanings:
+ * -1 sLen == hLen
+ * -2 salt length is autorecovered from signature
+ * -3 salt length is maximized
+ * -N reserved
+ */
+ if (sLen == RSA_PSS_SALTLEN_DIGEST) {
+ sLen = hLen;
+ } else if (sLen < RSA_PSS_SALTLEN_MAX) {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
+ goto err;
+ }
+
+ MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
+ emLen = RSA_size(rsa);
+ if (EM[0] & (0xFF << MSBits)) {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_FIRST_OCTET_INVALID);
+ goto err;
+ }
+ if (MSBits == 0) {
+ EM++;
+ emLen--;
+ }
+ if (emLen < hLen + 2) {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE);
+ goto err;
+ }
+ if (sLen == RSA_PSS_SALTLEN_MAX) {
+ sLen = emLen - hLen - 2;
+ } else if (sLen > emLen - hLen - 2) { /* sLen can be small negative */
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE);
+ goto err;
+ }
+ if (EM[emLen - 1] != 0xbc) {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_LAST_OCTET_INVALID);
+ goto err;
+ }
+ maskedDBLen = emLen - hLen - 1;
+ H = EM + maskedDBLen;
+ DB = OPENSSL_malloc(maskedDBLen);
+ if (DB == NULL) {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash) < 0)
+ goto err;
+ for (i = 0; i < maskedDBLen; i++)
+ DB[i] ^= EM[i];
+ if (MSBits)
+ DB[0] &= 0xFF >> (8 - MSBits);
+ for (i = 0; DB[i] == 0 && i < (maskedDBLen - 1); i++) ;
+ if (DB[i++] != 0x1) {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_RECOVERY_FAILED);
+ goto err;
+ }
+ if (sLen != RSA_PSS_SALTLEN_AUTO && (maskedDBLen - i) != sLen) {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
+ goto err;
+ }
+ if (!EVP_DigestInit_ex(ctx, Hash, NULL)
+ || !EVP_DigestUpdate(ctx, zeroes, sizeof(zeroes))
+ || !EVP_DigestUpdate(ctx, mHash, hLen))
+ goto err;
+ if (maskedDBLen - i) {
+ if (!EVP_DigestUpdate(ctx, DB + i, maskedDBLen - i))
+ goto err;
+ }
+ if (!EVP_DigestFinal_ex(ctx, H_, NULL))
+ goto err;
+ if (memcmp(H_, H, hLen)) {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_BAD_SIGNATURE);
+ ret = 0;
+ } else {
+ ret = 1;
+ }
+
+ err:
+ OPENSSL_free(DB);
+ EVP_MD_CTX_free(ctx);
+
+ return ret;
+
+}