src/wolfSSL/wolfcrypt/src/rsa.c
static int wc_RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen,
                            byte **output, enum wc_HashType hType, int mgf,
                            byte* optLabel, word32 labelLen)
{
    int hLen;
    int ret;
    byte h[WC_MAX_DIGEST_SIZE]; /* max digest size */
    byte* tmp;
    word32 idx;

    hLen = wc_HashGetDigestSize(hType);
    if ((hLen < 0) || (pkcsBlockLen < (2 * (word32)hLen + 2))) {
        return BAD_FUNC_ARG;
    }

    tmp = (byte*)XMALLOC(pkcsBlockLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    if (tmp == NULL) {
        return MEMORY_E;
    }
    XMEMSET(tmp, 0, pkcsBlockLen);

    /* find seedMask value */
    if ((ret = wc_MGF(mgf, (byte*)(pkcsBlock + (hLen + 1)),
                                    pkcsBlockLen - hLen - 1, tmp, hLen)) != 0) {
        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        return ret;
    }

    /* xor seedMask value with maskedSeed to get seed value */
    for (idx = 0; idx < (word32)hLen; idx++) {
        tmp[idx] = tmp[idx] ^ pkcsBlock[1 + idx];
    }

    /* get dbMask value */
    if ((ret = wc_MGF(mgf, tmp, hLen, tmp + hLen,
                                               pkcsBlockLen - hLen - 1)) != 0) {
        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        return ret;
    }

    /* get DB value by doing maskedDB xor dbMask */
    for (idx = 0; idx < (pkcsBlockLen - hLen - 1); idx++) {
        pkcsBlock[hLen + 1 + idx] = pkcsBlock[hLen + 1 + idx] ^ tmp[idx + hLen];
    }

    /* done with use of tmp buffer */
    XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);

    /* advance idx to index of PS and msg separator */
    idx = hLen + 2 + hLen;
    while (idx < pkcsBlockLen && pkcsBlock[idx] == 0) {idx++;}

    /* create hash of label for comparision with hash sent */
    if ((ret = wc_Hash(hType, optLabel, labelLen, h, hLen)) != 0) {
        return ret;
    }

    /* say no to chosen ciphertext attack.
       Comparison of lHash, Y, and separator value needs to all happen in
       constant time.
       Attackers should not be able to get error condition from the timing of
       these checks.
     */
    ret = 0;
    ret |= ConstantCompare(pkcsBlock + hLen + 1, h, hLen);
    ret += pkcsBlock[idx++] ^ 0x01; /* separator value is 0x01 */
    ret += pkcsBlock[0]     ^ 0x00; /* Y, the first value, should be 0 */

    if (ret != 0) {
        return BAD_PADDING_E;
    }

    /* adjust pointer to correct location in array and return size of M */
    *output = (byte*)(pkcsBlock + idx);
    return pkcsBlockLen - idx;
}
/* UnPad plaintext, set start to *output, return length of plaintext,
 * < 0 on error */
UnPad plaintext, set start to *output, return length of plaintext,
< 0 on error
UnPad plaintext set start to * output return length of plaintext < 0 on error
static int wc_RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen,
                            byte **output, enum wc_HashType hType, int mgf,
                            byte* optLabel, word32 labelLen)
{
    int hLen;
    int ret;
    byte h[WC_MAX_DIGEST_SIZE]; 
    byte* tmp;
    word32 idx;
    hLen = wc_HashGetDigestSize(hType);
    if ((hLen < 0) || (pkcsBlockLen < (2 * (word32)hLen + 2))) {
        return BAD_FUNC_ARG;
    }
    tmp = (byte*)XMALLOC(pkcsBlockLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    if (tmp == NULL) {
        return MEMORY_E;
    }
    XMEMSET(tmp, 0, pkcsBlockLen);
    if ((ret = wc_MGF(mgf, (byte*)(pkcsBlock + (hLen + 1)),
                                    pkcsBlockLen - hLen - 1, tmp, hLen)) != 0) {
        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        return ret;
    }
    for (idx = 0; idx < (word32)hLen; idx++) {
        tmp[idx] = tmp[idx] ^ pkcsBlock[1 + idx];
    }
    if ((ret = wc_MGF(mgf, tmp, hLen, tmp + hLen,
                                               pkcsBlockLen - hLen - 1)) != 0) {
        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        return ret;
    }
    for (idx = 0; idx < (pkcsBlockLen - hLen - 1); idx++) {
        pkcsBlock[hLen + 1 + idx] = pkcsBlock[hLen + 1 + idx] ^ tmp[idx + hLen];
    }
    XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    idx = hLen + 2 + hLen;
    while (idx < pkcsBlockLen && pkcsBlock[idx] == 0) {idx++;}
    if ((ret = wc_Hash(hType, optLabel, labelLen, h, hLen)) != 0) {
        return ret;
    }
    ret = 0;
    ret |= ConstantCompare(pkcsBlock + hLen + 1, h, hLen);
    ret += pkcsBlock[idx++] ^ 0x01; 
    ret += pkcsBlock[0]     ^ 0x00; 
    if (ret != 0) {
        return BAD_PADDING_E;
    }
    *output = (byte*)(pkcsBlock + idx);
    return pkcsBlockLen - idx;
}
static int wc_RsaUnPad_OAEP ( byte * pkcsBlock , unsigned int pkcsBlockLen , byte * * output , enum wc_HashType hType , int mgf , byte * optLabel , word32 labelLen ) { int hLen ; int ret ; byte h [ WC_MAX_DIGEST_SIZE ] ; byte * tmp ; word32 idx ; hLen = wc_HashGetDigestSize ( hType ) ; if ( ( hLen < 0 ) || ( pkcsBlockLen < ( 2 * ( word32 ) hLen + 2 ) ) ) { return BAD_FUNC_ARG ; } tmp = ( byte * ) XMALLOC ( pkcsBlockLen , NULL , DYNAMIC_TYPE_TMP_BUFFER ) ; if ( tmp == NULL ) { return MEMORY_E ; } XMEMSET ( tmp , 0 , pkcsBlockLen ) ; if ( ( ret = wc_MGF ( mgf , ( byte * ) ( pkcsBlock + ( hLen + 1 ) ) , pkcsBlockLen - hLen - 1 , tmp , hLen ) ) != 0 ) { XFREE ( tmp , NULL , DYNAMIC_TYPE_TMP_BUFFER ) ; return ret ; } for ( idx = 0 ; idx < ( word32 ) hLen ; idx ++ ) { tmp [ idx ] = tmp [ idx ] ^ pkcsBlock [ 1 + idx ] ; } if ( ( ret = wc_MGF ( mgf , tmp , hLen , tmp + hLen , pkcsBlockLen - hLen - 1 ) ) != 0 ) { XFREE ( tmp , NULL , DYNAMIC_TYPE_TMP_BUFFER ) ; return ret ; } for ( idx = 0 ; idx < ( pkcsBlockLen - hLen - 1 ) ; idx ++ ) { pkcsBlock [ hLen + 1 + idx ] = pkcsBlock [ hLen + 1 + idx ] ^ tmp [ idx + hLen ] ; } XFREE ( tmp , NULL , DYNAMIC_TYPE_TMP_BUFFER ) ; idx = hLen + 2 + hLen ; while ( idx < pkcsBlockLen && pkcsBlock [ idx ] == 0 ) { idx ++ ; } if ( ( ret = wc_Hash ( hType , optLabel , labelLen , h , hLen ) ) != 0 ) { return ret ; } ret = 0 ; ret |= ConstantCompare ( pkcsBlock + hLen + 1 , h , hLen ) ; ret += pkcsBlock [ idx ++ ] ^ 0x01 ; ret += pkcsBlock [ 0 ] ^ 0x00 ; if ( ret != 0 ) { return BAD_PADDING_E ; } * output = ( byte * ) ( pkcsBlock + idx ) ; return pkcsBlockLen - idx ; }
UnPad plaintext, set start to *output, return length of plaintext,
 < 0 on error
UnPad plaintext set start to * output return length of plaintext < 0 on error
/* max digest size */ /* find seedMask value */ /* xor seedMask value with maskedSeed to get seed value */ /* get dbMask value */ /* get DB value by doing maskedDB xor dbMask */ /* done with use of tmp buffer */ /* advance idx to index of PS and msg separator */ /* create hash of label for comparision with hash sent */ /* say no to chosen ciphertext attack.
       Comparison of lHash, Y, and separator value needs to all happen in
       constant time.
       Attackers should not be able to get error condition from the timing of
       these checks.
     */ /* separator value is 0x01 */ /* Y, the first value, should be 0 */ /* adjust pointer to correct location in array and return size of M */