/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
 * project 2005.
 */
/* ====================================================================
 * Copyright (c) 2005 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com). */

#include <openssl/rsa.h>

#include <assert.h>

#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/rand.h>
#include <openssl/sha.h>

#include "internal.h"

/* TODO(fork): don't the check functions have to be constant time? */

int RSA_padding_add_PKCS1_type_1(uint8_t *to, unsigned tlen,
                                 const uint8_t *from, unsigned flen) {
  unsigned j;
  uint8_t *p;

  if (tlen < RSA_PKCS1_PADDING_SIZE) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_type_1,
                      RSA_R_KEY_SIZE_TOO_SMALL);
    return 0;
  }

  if (flen > tlen - RSA_PKCS1_PADDING_SIZE) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_type_1,
                      RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
    return 0;
  }

  p = (uint8_t *)to;

  *(p++) = 0;
  *(p++) = 1; /* Private Key BT (Block Type) */

  /* pad out with 0xff data */
  j = tlen - 3 - flen;
  memset(p, 0xff, j);
  p += j;
  *(p++) = 0;
  memcpy(p, from, (unsigned int)flen);
  return 1;
}

int RSA_padding_check_PKCS1_type_1(uint8_t *to, unsigned tlen,
                                   const uint8_t *from, unsigned flen) {
  unsigned i, j;
  const uint8_t *p;

  if (flen < 2) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_1,
                      RSA_R_DATA_TOO_SMALL);
    return -1;
  }

  p = from;
  if ((*(p++) != 0) || (*(p++) != 1)) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_1,
                      RSA_R_BLOCK_TYPE_IS_NOT_01);
    return -1;
  }

  /* scan over padding data */
  j = flen - 2; /* one for leading 00, one for type. */
  for (i = 0; i < j; i++) {
    /* should decrypt to 0xff */
    if (*p != 0xff) {
      if (*p == 0) {
        p++;
        break;
      } else {
        OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_1,
                          RSA_R_BAD_FIXED_HEADER_DECRYPT);
        return -1;
      }
    }
    p++;
  }

  if (i == j) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_1,
                      RSA_R_NULL_BEFORE_BLOCK_MISSING);
    return -1;
  }

  if (i < 8) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_1,
                      RSA_R_BAD_PAD_BYTE_COUNT);
    return -1;
  }
  i++; /* Skip over the '\0' */
  j -= i;
  if (j > tlen) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_1,
                      RSA_R_DATA_TOO_LARGE);
    return -1;
  }
  memcpy(to, p, j);

  return j;
}

int RSA_padding_add_PKCS1_type_2(uint8_t *to, unsigned tlen,
                                 const uint8_t *from, unsigned flen) {
  unsigned i, j;
  uint8_t *p;

  if (tlen < RSA_PKCS1_PADDING_SIZE) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_type_2,
                      RSA_R_KEY_SIZE_TOO_SMALL);
    return 0;
  }

  if (flen > tlen - RSA_PKCS1_PADDING_SIZE) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_type_2,
                      RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
    return 0;
  }

  p = (unsigned char *)to;

  *(p++) = 0;
  *(p++) = 2; /* Public Key BT (Block Type) */

  /* pad out with non-zero random data */
  j = tlen - 3 - flen;

  if (!RAND_bytes(p, j)) {
    return 0;
  }

  for (i = 0; i < j; i++) {
    while (*p == 0) {
      if (!RAND_bytes(p, 1)) {
        return 0;
      }
    }
    p++;
  }

  *(p++) = 0;

  memcpy(p, from, (unsigned int)flen);
  return 1;
}

/* constant_time_byte_eq returns 1 if |x| == |y| and 0 otherwise. */
static int constant_time_byte_eq(unsigned char a, unsigned char b) {
  unsigned char z = ~(a ^ b);
  z &= z >> 4;
  z &= z >> 2;
  z &= z >> 1;

  return z;
}

/* constant_time_select returns |x| if |v| is 1 and |y| if |v| is 0.
 * Its behavior is undefined if |v| takes any other value. */
static int constant_time_select(int v, int x, int y) {
  return ((~(v - 1)) & x) | ((v - 1) & y);
}

/* constant_time_le returns 1 if |x| <= |y| and 0 otherwise.
 * |x| and |y| must be positive. */
static int constant_time_le(int x, int y) {
  return ((x - y - 1) >> (sizeof(int) * 8 - 1)) & 1;
}

int RSA_message_index_PKCS1_type_2(const uint8_t *from, size_t from_len,
                                   size_t *out_index) {
  size_t i;
  int first_byte_is_zero, second_byte_is_two, looking_for_index;
  int valid_index, zero_index = 0;

  /* PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography
   * Standard", section 7.2.2. */
  if (from_len < RSA_PKCS1_PADDING_SIZE) {
    /* |from| is zero-padded to the size of the RSA modulus, a public value, so
     * this can be rejected in non-constant time. */
    *out_index = 0;
    return 0;
  }

  first_byte_is_zero = constant_time_byte_eq(from[0], 0);
  second_byte_is_two = constant_time_byte_eq(from[1], 2);

  looking_for_index = 1;
  for (i = 2; i < from_len; i++) {
    int equals0 = constant_time_byte_eq(from[i], 0);
    zero_index =
        constant_time_select(looking_for_index & equals0, i, zero_index);
    looking_for_index = constant_time_select(equals0, 0, looking_for_index);
  }

  /* The input must begin with 00 02. */
  valid_index = first_byte_is_zero;
  valid_index &= second_byte_is_two;

  /* We must have found the end of PS. */
  valid_index &= ~looking_for_index;

  /* PS must be at least 8 bytes long, and it starts two bytes into |from|. */
  valid_index &= constant_time_le(2 + 8, zero_index);

  /* Skip the zero byte. */
  zero_index++;

  *out_index = constant_time_select(valid_index, zero_index, 0);
  return valid_index;
}

int RSA_padding_check_PKCS1_type_2(uint8_t *to, unsigned tlen,
                                   const uint8_t *from, unsigned flen) {
  size_t msg_index, msg_len;

  if (flen == 0) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_2,
                      RSA_R_EMPTY_PUBLIC_KEY);
    return -1;
  }

  /* NOTE: Although |RSA_message_index_PKCS1_type_2| itself is constant time,
   * the API contracts of this function and |RSA_decrypt| with
   * |RSA_PKCS1_PADDING| make it impossible to completely avoid Bleichenbacher's
   * attack. */
  if (!RSA_message_index_PKCS1_type_2(from, flen, &msg_index)) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_2,
                      RSA_R_PKCS_DECODING_ERROR);
    return -1;
  }

  msg_len = flen - msg_index;
  if (msg_len > tlen) {
    /* This shouldn't happen because this function is always called with |tlen|
     * the key size and |flen| is bounded by the key size. */
    OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_2,
                      RSA_R_PKCS_DECODING_ERROR);
    return -1;
  }
  memcpy(to, &from[msg_index], msg_len);
  return msg_len;
}

int RSA_padding_add_none(uint8_t *to, unsigned tlen, const uint8_t *from, unsigned flen) {
  if (flen > tlen) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_add_none,
                      RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
    return 0;
  }

  if (flen < tlen) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_add_none,
                      RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE);
    return 0;
  }

  memcpy(to, from, (unsigned int)flen);
  return 1;
}

int RSA_padding_check_none(uint8_t *to, unsigned tlen, const uint8_t *from,
                           unsigned flen) {
  if (flen > tlen) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_check_none, RSA_R_DATA_TOO_LARGE);
    return -1;
  }

  memcpy(to, from, flen);
  return flen;
}

int PKCS1_MGF1(uint8_t *mask, unsigned len, const uint8_t *seed,
               unsigned seedlen, const EVP_MD *dgst) {
  unsigned outlen = 0;
  uint32_t i;
  uint8_t cnt[4];
  EVP_MD_CTX c;
  uint8_t md[EVP_MAX_MD_SIZE];
  unsigned mdlen;
  int ret = -1;

  EVP_MD_CTX_init(&c);
  mdlen = EVP_MD_size(dgst);

  for (i = 0; outlen < len; i++) {
    cnt[0] = (uint8_t)((i >> 24) & 255);
    cnt[1] = (uint8_t)((i >> 16) & 255);
    cnt[2] = (uint8_t)((i >> 8)) & 255;
    cnt[3] = (uint8_t)(i & 255);
    if (!EVP_DigestInit_ex(&c, dgst, NULL) ||
        !EVP_DigestUpdate(&c, seed, seedlen) || !EVP_DigestUpdate(&c, cnt, 4)) {
      goto err;
    }

    if (outlen + mdlen <= len) {
      if (!EVP_DigestFinal_ex(&c, mask + outlen, NULL)) {
        goto err;
      }
      outlen += mdlen;
    } else {
      if (!EVP_DigestFinal_ex(&c, md, NULL)) {
        goto err;
      }
      memcpy(mask + outlen, md, len - outlen);
      outlen = len;
    }
  }
  ret = 0;

err:
  EVP_MD_CTX_cleanup(&c);
  return ret;
}

int RSA_padding_add_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
                                    const uint8_t *from, unsigned flen,
                                    const uint8_t *param, unsigned plen,
                                    const EVP_MD *md, const EVP_MD *mgf1md) {
  unsigned i, emlen, mdlen;
  uint8_t *db, *seed;
  uint8_t *dbmask = NULL, seedmask[EVP_MAX_MD_SIZE];
  int ret = 0;

  if (md == NULL) {
    md = EVP_sha1();
  }
  if (mgf1md == NULL) {
    mgf1md = md;
  }

  mdlen = EVP_MD_size(md);

  if (tlen < 2 * mdlen + 2) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_OAEP_mgf1,
                      RSA_R_KEY_SIZE_TOO_SMALL);
    return 0;
  }

  emlen = tlen - 1;
  if (flen > emlen - 2 * mdlen - 1) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_OAEP_mgf1,
                      RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
    return 0;
  }

  if (emlen < 2 * mdlen + 1) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_OAEP_mgf1,
                      RSA_R_KEY_SIZE_TOO_SMALL);
    return 0;
  }

  to[0] = 0;
  seed = to + 1;
  db = to + mdlen + 1;

  if (!EVP_Digest((void *)param, plen, db, NULL, md, NULL)) {
    return 0;
  }
  memset(db + mdlen, 0, emlen - flen - 2 * mdlen - 1);
  db[emlen - flen - mdlen - 1] = 0x01;
  memcpy(db + emlen - flen - mdlen, from, flen);
  if (!RAND_bytes(seed, mdlen)) {
    return 0;
  }

  dbmask = OPENSSL_malloc(emlen - mdlen);
  if (dbmask == NULL) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_OAEP_mgf1,
                      ERR_R_MALLOC_FAILURE);
    return 0;
  }

  if (PKCS1_MGF1(dbmask, emlen - mdlen, seed, mdlen, mgf1md) < 0) {
    goto out;
  }
  for (i = 0; i < emlen - mdlen; i++) {
    db[i] ^= dbmask[i];
  }

  if (PKCS1_MGF1(seedmask, mdlen, db, emlen - mdlen, mgf1md) < 0) {
    goto out;
  }
  for (i = 0; i < mdlen; i++) {
    seed[i] ^= seedmask[i];
  }
  ret = 1;

out:
  if (dbmask != NULL) {
    OPENSSL_free(dbmask);
  }
  return ret;
}

int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
                                      const uint8_t *from, unsigned flen,
                                      const uint8_t *param, unsigned plen,
                                      const EVP_MD *md, const EVP_MD *mgf1md) {
  unsigned i, dblen, mlen = -1, mdlen;
  const uint8_t *maskeddb, *maskedseed;
  uint8_t *db = NULL, seed[EVP_MAX_MD_SIZE], phash[EVP_MAX_MD_SIZE];
  int bad, looking_for_one_byte, one_index = 0;

  if (md == NULL) {
    md = EVP_sha1();
  }
  if (mgf1md == NULL) {
    mgf1md = md;
  }

  mdlen = EVP_MD_size(md);

  /* The encoded message is one byte smaller than the modulus to ensure that it
   * doesn't end up greater than the modulus. Thus there's an extra "+1" here
   * compared to https://tools.ietf.org/html/rfc2437#section-9.1.1.2. */
  if (flen < 1 + 2*mdlen + 1) {
    /* 'flen' is the length of the modulus, i.e. does not depend on the
     * particular ciphertext. */
    goto decoding_err;
  }

  dblen = flen - mdlen - 1;
  db = OPENSSL_malloc(dblen);
  if (db == NULL) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_OAEP_mgf1,
                      ERR_R_MALLOC_FAILURE);
    goto err;
  }

  maskedseed = from + 1;
  maskeddb = from + 1 + mdlen;

  if (PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md)) {
    goto err;
  }
  for (i = 0; i < mdlen; i++) {
    seed[i] ^= maskedseed[i];
  }

  if (PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md)) {
    goto err;
  }
  for (i = 0; i < dblen; i++) {
    db[i] ^= maskeddb[i];
  }

  if (!EVP_Digest((void *)param, plen, phash, NULL, md, NULL)) {
    goto err;
  }

  bad = CRYPTO_memcmp(db, phash, mdlen);
  bad |= from[0];

  looking_for_one_byte = 1;
  for (i = mdlen; i < dblen; i++) {
    int equals1 = constant_time_byte_eq(db[i], 1);
    int equals0 = constant_time_byte_eq(db[i], 0);
    one_index =
        constant_time_select(looking_for_one_byte & equals1, i, one_index);
    looking_for_one_byte =
        constant_time_select(equals1, 0, looking_for_one_byte);
    bad |= looking_for_one_byte & ~equals0;
  }

  bad |= looking_for_one_byte;

  if (bad) {
    goto decoding_err;
  }

  one_index++;
  mlen = dblen - one_index;
  if (tlen < mlen) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_OAEP_mgf1,
                      RSA_R_DATA_TOO_LARGE);
    mlen = -1;
  } else {
    memcpy(to, db + one_index, mlen);
  }

  OPENSSL_free(db);
  return mlen;

decoding_err:
  /* to avoid chosen ciphertext attacks, the error message should not reveal
   * which kind of decoding error happened */
  OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_OAEP_mgf1,
                    RSA_R_OAEP_DECODING_ERROR);
 err:
  if (db != NULL) {
    OPENSSL_free(db);
  }
  return -1;
}

static const unsigned char zeroes[] = {0,0,0,0,0,0,0,0};

int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const uint8_t *mHash,
                              const EVP_MD *Hash, const EVP_MD *mgf1Hash,
                              const uint8_t *EM, int sLen) {
  int i;
  int ret = 0;
  int maskedDBLen, MSBits, emLen;
  size_t hLen;
  const uint8_t *H;
  uint8_t *DB = NULL;
  EVP_MD_CTX ctx;
  uint8_t H_[EVP_MAX_MD_SIZE];
  EVP_MD_CTX_init(&ctx);

  if (mgf1Hash == NULL) {
    mgf1Hash = Hash;
  }

  hLen = EVP_MD_size(Hash);

  /* 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) {
    OPENSSL_PUT_ERROR(RSA, 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)) {
    OPENSSL_PUT_ERROR(RSA, RSA_verify_PKCS1_PSS_mgf1,
                      RSA_R_FIRST_OCTET_INVALID);
    goto err;
  }
  if (MSBits == 0) {
    EM++;
    emLen--;
  }
  if (emLen < ((int)hLen + sLen + 2)) {
    /* sLen can be small negative */
    OPENSSL_PUT_ERROR(RSA, RSA_verify_PKCS1_PSS_mgf1, RSA_R_DATA_TOO_LARGE);
    goto err;
  }
  if (EM[emLen - 1] != 0xbc) {
    OPENSSL_PUT_ERROR(RSA, 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) {
    OPENSSL_PUT_ERROR(RSA, 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) {
    OPENSSL_PUT_ERROR(RSA, RSA_verify_PKCS1_PSS_mgf1,
                      RSA_R_SLEN_RECOVERY_FAILED);
    goto err;
  }
  if (sLen >= 0 && (maskedDBLen - i) != sLen) {
    OPENSSL_PUT_ERROR(RSA, 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)) {
    OPENSSL_PUT_ERROR(RSA, 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;
}

int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
                                   const unsigned char *mHash,
                                   const EVP_MD *Hash, const EVP_MD *mgf1Hash,
                                   int sLen) {
  int i;
  int ret = 0;
  size_t maskedDBLen, MSBits, emLen;
  size_t hLen;
  unsigned char *H, *salt = NULL, *p;
  EVP_MD_CTX ctx;

  if (mgf1Hash == NULL) {
    mgf1Hash = Hash;
  }

  hLen = EVP_MD_size(Hash);

  /* Negative sLen has special meanings:
   *	-1	sLen == hLen
   *	-2	salt length is maximized
   *	-N	reserved */
  if (sLen == -1) {
    sLen = hLen;
  } else if (sLen == -2) {
    sLen = -2;
  } else if (sLen < -2) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1,
                      RSA_R_SLEN_CHECK_FAILED);
    goto err;
  }

  if (BN_is_zero(rsa->n)) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1,
                      RSA_R_EMPTY_PUBLIC_KEY);
    goto err;
  }

  MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
  emLen = RSA_size(rsa);
  if (MSBits == 0) {
    assert(emLen >= 1);
    *EM++ = 0;
    emLen--;
  }
  if (sLen == -2) {
    if (emLen < hLen + 2) {
      OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1,
                        RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
      goto err;
    }
    sLen = emLen - hLen - 2;
  } else if (emLen < hLen + sLen + 2) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1,
                      RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
    goto err;
  }
  if (sLen > 0) {
    salt = OPENSSL_malloc(sLen);
    if (!salt) {
      OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1,
                        ERR_R_MALLOC_FAILURE);
      goto err;
    }
    if (!RAND_bytes(salt, sLen)) {
      goto err;
    }
  }
  maskedDBLen = emLen - hLen - 1;
  H = EM + maskedDBLen;
  EVP_MD_CTX_init(&ctx);
  if (!EVP_DigestInit_ex(&ctx, Hash, NULL) ||
      !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes) ||
      !EVP_DigestUpdate(&ctx, mHash, hLen)) {
    goto err;
  }
  if (sLen && !EVP_DigestUpdate(&ctx, salt, sLen)) {
    goto err;
  }
  if (!EVP_DigestFinal_ex(&ctx, H, NULL)) {
    goto err;
  }
  EVP_MD_CTX_cleanup(&ctx);

  /* Generate dbMask in place then perform XOR on it */
  if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash)) {
    goto err;
  }

  p = EM;

  /* Initial PS XORs with all zeroes which is a NOP so just update
   * pointer. Note from a test above this value is guaranteed to
   * be non-negative. */
  p += emLen - sLen - hLen - 2;
  *p++ ^= 0x1;
  if (sLen > 0) {
    for (i = 0; i < sLen; i++) {
      *p++ ^= salt[i];
    }
  }
  if (MSBits) {
    EM[0] &= 0xFF >> (8 - MSBits);
  }

  /* H is already in place so just set final 0xbc */

  EM[emLen - 1] = 0xbc;

  ret = 1;

err:
  if (salt) {
    OPENSSL_free(salt);
  }

  return ret;
}
