Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions
rsawrapr.c File Reference
#include "blapi.h"
#include "softoken.h"
#include "sechash.h"
#include "lowkeyi.h"
#include "secerr.h"

Go to the source code of this file.

Defines

#define RSA_BLOCK_MIN_PAD_LEN   8
#define RSA_BLOCK_FIRST_OCTET   0x00
#define RSA_BLOCK_PRIVATE0_PAD_OCTET   0x00
#define RSA_BLOCK_PRIVATE_PAD_OCTET   0xff
#define RSA_BLOCK_AFTER_PAD_OCTET   0x00
#define OAEP_SALT_LEN   8
#define OAEP_PAD_LEN   8
#define OAEP_PAD_OCTET   0x00
#define FLAT_BUFSIZE   512 /* bytes to hold flattened SHA1Context. */

Functions

static SHA1Context * SHA1_CloneContext (SHA1Context *original)
static SECStatus oaep_xor_with_h1 (unsigned char *data, unsigned int datalen, unsigned char *salt, unsigned int saltlen)
static SECStatus oaep_xor_with_h2 (unsigned char *salt, unsigned int saltlen, unsigned char *data, unsigned int datalen)
static unsigned char * rsa_FormatOneBlock (unsigned modulusLen, RSA_BlockType blockType, SECItem *data)
static SECStatus rsa_FormatBlock (SECItem *result, unsigned modulusLen, RSA_BlockType blockType, SECItem *data)
SECStatus RSA_Sign (NSSLOWKEYPrivateKey *key, unsigned char *output, unsigned int *output_len, unsigned int maxOutputLen, unsigned char *input, unsigned int input_len)
SECStatus RSA_CheckSign (NSSLOWKEYPublicKey *key, unsigned char *sign, unsigned int sign_len, unsigned char *hash, unsigned int hash_len)
SECStatus RSA_CheckSignRecover (NSSLOWKEYPublicKey *key, unsigned char *data, unsigned int *data_len, unsigned int max_output_len, unsigned char *sign, unsigned int sign_len)
SECStatus RSA_EncryptBlock (NSSLOWKEYPublicKey *key, unsigned char *output, unsigned int *output_len, unsigned int max_output_len, unsigned char *input, unsigned int input_len)
SECStatus RSA_DecryptBlock (NSSLOWKEYPrivateKey *key, unsigned char *output, unsigned int *output_len, unsigned int max_output_len, unsigned char *input, unsigned int input_len)
SECStatus RSA_SignRaw (NSSLOWKEYPrivateKey *key, unsigned char *output, unsigned int *output_len, unsigned int maxOutputLen, unsigned char *input, unsigned int input_len)
SECStatus RSA_CheckSignRaw (NSSLOWKEYPublicKey *key, unsigned char *sign, unsigned int sign_len, unsigned char *hash, unsigned int hash_len)
SECStatus RSA_CheckSignRecoverRaw (NSSLOWKEYPublicKey *key, unsigned char *data, unsigned int *data_len, unsigned int max_output_len, unsigned char *sign, unsigned int sign_len)
SECStatus RSA_EncryptRaw (NSSLOWKEYPublicKey *key, unsigned char *output, unsigned int *output_len, unsigned int max_output_len, unsigned char *input, unsigned int input_len)
SECStatus RSA_DecryptRaw (NSSLOWKEYPrivateKey *key, unsigned char *output, unsigned int *output_len, unsigned int max_output_len, unsigned char *input, unsigned int input_len)

Define Documentation

#define FLAT_BUFSIZE   512 /* bytes to hold flattened SHA1Context. */

Definition at line 59 of file rsawrapr.c.

Definition at line 56 of file rsawrapr.c.

#define OAEP_PAD_OCTET   0x00

Definition at line 57 of file rsawrapr.c.

Definition at line 55 of file rsawrapr.c.

Definition at line 53 of file rsawrapr.c.

Definition at line 50 of file rsawrapr.c.

Definition at line 49 of file rsawrapr.c.

Definition at line 51 of file rsawrapr.c.

Definition at line 52 of file rsawrapr.c.


Function Documentation

static SECStatus oaep_xor_with_h1 ( unsigned char *  data,
unsigned int  datalen,
unsigned char *  salt,
unsigned int  saltlen 
) [static]

Definition at line 94 of file rsawrapr.c.

{
    SHA1Context *sha1cx;
    unsigned char *dp, *dataend;
    unsigned char end_octet;

    sha1cx = SHA1_NewContext();
    if (sha1cx == NULL) {
       return SECFailure;
    }

    /*
     * Get a hash of salt started; we will use it several times,
     * adding in a different end octet (x00, x01, x02, ...).
     */
    SHA1_Begin (sha1cx);
    SHA1_Update (sha1cx, salt, saltlen);
    end_octet = 0;

    dp = data;
    dataend = data + datalen;

    while (dp < dataend) {
       SHA1Context *sha1cx_h1;
       unsigned int sha1len, sha1off;
       unsigned char sha1[SHA1_LENGTH];

       /*
        * Create hash of (salt || end_octet)
        */
       sha1cx_h1 = SHA1_CloneContext (sha1cx);
       SHA1_Update (sha1cx_h1, &end_octet, 1);
       SHA1_End (sha1cx_h1, sha1, &sha1len, sizeof(sha1));
       SHA1_DestroyContext (sha1cx_h1, PR_TRUE);
       PORT_Assert (sha1len == SHA1_LENGTH);

       /*
        * XOR that hash with the data.
        * When we have fewer than SHA1_LENGTH octets of data
        * left to xor, use just the low-order ones of the hash.
        */
       sha1off = 0;
       if ((dataend - dp) < SHA1_LENGTH)
           sha1off = SHA1_LENGTH - (dataend - dp);
       while (sha1off < SHA1_LENGTH)
           *dp++ ^= sha1[sha1off++];

       /*
        * Bump for next hash chunk.
        */
       end_octet++;
    }

    return SECSuccess;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus oaep_xor_with_h2 ( unsigned char *  salt,
unsigned int  saltlen,
unsigned char *  data,
unsigned int  datalen 
) [static]

Definition at line 155 of file rsawrapr.c.

{
    unsigned char sha1[SHA1_LENGTH];
    unsigned char *psalt, *psha1, *saltend;
    SECStatus rv;

    /*
     * Create a hash of data.
     */
    rv = SHA1_HashBuf (sha1, data, datalen);
    if (rv != SECSuccess) {
       return rv;
    }

    /*
     * XOR the low-order octets of that hash with salt.
     */
    PORT_Assert (saltlen <= SHA1_LENGTH);
    saltend = salt + saltlen;
    psalt = salt;
    psha1 = sha1 + SHA1_LENGTH - saltlen;
    while (psalt < saltend) {
       *psalt++ ^= *psha1++;
    }

    return SECSuccess;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus RSA_CheckSign ( NSSLOWKEYPublicKey *  key,
unsigned char *  sign,
unsigned int  sign_len,
unsigned char *  hash,
unsigned int  hash_len 
)

Definition at line 498 of file rsawrapr.c.

{
    SECStatus       rv;
    unsigned int    modulus_len = nsslowkey_PublicModulusLen(key);
    unsigned int    i;
    unsigned char * buffer;

    modulus_len = nsslowkey_PublicModulusLen(key);
    if (sign_len != modulus_len) 
       goto failure;
    /*
     * 0x00 || BT || Pad || 0x00 || ActualData
     *
     * The "3" below is the first octet + the second octet + the 0x00
     * octet that always comes just before the ActualData.
     */
    if (hash_len > modulus_len - (3 + RSA_BLOCK_MIN_PAD_LEN)) 
       goto failure;
    PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
    if (key->keyType != NSSLOWKEYRSAKey)
       goto failure;

    buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
    if (!buffer)
       goto failure;

    rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign);
    if (rv != SECSuccess)
       goto loser;

    /*
     * check the padding that was used
     */
    if (buffer[0] != 0 || buffer[1] != 1) 
       goto loser;
    for (i = 2; i < modulus_len - hash_len - 1; i++) {
       if (buffer[i] != 0xff) 
           goto loser;
    }
    if (buffer[i] != 0) 
       goto loser;

    /*
     * make sure we get the same results
     */
    if (PORT_Memcmp(buffer + modulus_len - hash_len, hash, hash_len) != 0)
       goto loser;

    PORT_Free(buffer);
    return SECSuccess;

loser:
    PORT_Free(buffer);
failure:
    return SECFailure;
}

Here is the call graph for this function:

SECStatus RSA_CheckSignRaw ( NSSLOWKEYPublicKey *  key,
unsigned char *  sign,
unsigned int  sign_len,
unsigned char *  hash,
unsigned int  hash_len 
)

Definition at line 765 of file rsawrapr.c.

{
    SECStatus       rv;
    unsigned int    modulus_len = nsslowkey_PublicModulusLen(key);
    unsigned char * buffer;

    if (sign_len != modulus_len) 
       goto failure;
    if (hash_len > modulus_len) 
       goto failure;
    PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
    if (key->keyType != NSSLOWKEYRSAKey)
       goto failure;

    buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
    if (!buffer)
       goto failure;

    rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign);
    if (rv != SECSuccess)
       goto loser;

    /*
     * make sure we get the same results
     */
    /* NOTE: should we verify the leading zeros? */
    if (PORT_Memcmp(buffer + (modulus_len-hash_len), hash, hash_len) != 0)
       goto loser;

    PORT_Free(buffer);
    return SECSuccess;

loser:
    PORT_Free(buffer);
failure:
    return SECFailure;
}

Here is the call graph for this function:

SECStatus RSA_CheckSignRecover ( NSSLOWKEYPublicKey *  key,
unsigned char *  data,
unsigned int data_len,
unsigned int  max_output_len,
unsigned char *  sign,
unsigned int  sign_len 
)

Definition at line 561 of file rsawrapr.c.

{
    SECStatus       rv;
    unsigned int    modulus_len = nsslowkey_PublicModulusLen(key);
    unsigned int    i;
    unsigned char * buffer;

    if (sign_len != modulus_len) 
       goto failure;
    PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
    if (key->keyType != NSSLOWKEYRSAKey)
       goto failure;

    buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
    if (!buffer)
       goto failure;

    rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign);
    if (rv != SECSuccess)
       goto loser;
    *data_len = 0;

    /*
     * check the padding that was used
     */
    if (buffer[0] != 0 || buffer[1] != 1) 
       goto loser;
    for (i = 2; i < modulus_len; i++) {
       if (buffer[i] == 0) {
           *data_len = modulus_len - i - 1;
           break;
       }
       if (buffer[i] != 0xff) 
           goto loser;
    }
    if (*data_len == 0) 
       goto loser;
    if (*data_len > max_output_len) 
       goto loser;

    /*
     * make sure we get the same results
     */
    PORT_Memcpy(data,buffer + modulus_len - *data_len, *data_len);

    PORT_Free(buffer);
    return SECSuccess;

loser:
    PORT_Free(buffer);
failure:
    return SECFailure;
}

Here is the call graph for this function:

SECStatus RSA_CheckSignRecoverRaw ( NSSLOWKEYPublicKey *  key,
unsigned char *  data,
unsigned int data_len,
unsigned int  max_output_len,
unsigned char *  sign,
unsigned int  sign_len 
)

Definition at line 809 of file rsawrapr.c.

{
    SECStatus      rv;
    unsigned int   modulus_len = nsslowkey_PublicModulusLen(key);

    if (sign_len != modulus_len) 
       goto failure;
    if (max_output_len < modulus_len) 
       goto failure;
    PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
    if (key->keyType != NSSLOWKEYRSAKey)
       goto failure;

    rv = RSA_PublicKeyOp(&key->u.rsa, data, sign);
    if (rv != SECSuccess)
       goto failure;

    *data_len = modulus_len;
    return SECSuccess;

failure:
    return SECFailure;
}

Here is the call graph for this function:

SECStatus RSA_DecryptBlock ( NSSLOWKEYPrivateKey *  key,
unsigned char *  output,
unsigned int output_len,
unsigned int  max_output_len,
unsigned char *  input,
unsigned int  input_len 
)

Definition at line 665 of file rsawrapr.c.

{
    SECStatus       rv;
    unsigned int    modulus_len = nsslowkey_PrivateModulusLen(key);
    unsigned int    i;
    unsigned char * buffer;

    PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
    if (key->keyType != NSSLOWKEYRSAKey)
       goto failure;
    if (input_len != modulus_len)
       goto failure;

    buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
    if (!buffer)
       goto failure;

    rv = RSA_PrivateKeyOp(&key->u.rsa, buffer, input);
    if (rv != SECSuccess) {
       if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
           sftk_fatalError = PR_TRUE;
       }
       goto loser;
    }

    if (buffer[0] != 0 || buffer[1] != 2) 
       goto loser;
    *output_len = 0;
    for (i = 2; i < modulus_len; i++) {
       if (buffer[i] == 0) {
           *output_len = modulus_len - i - 1;
           break;
       }
    }
    if (*output_len == 0) 
       goto loser;
    if (*output_len > max_output_len) 
       goto loser;

    PORT_Memcpy(output, buffer + modulus_len - *output_len, *output_len);

    PORT_Free(buffer);
    return SECSuccess;

loser:
    PORT_Free(buffer);
failure:
    return SECFailure;
}

Here is the call graph for this function:

SECStatus RSA_DecryptRaw ( NSSLOWKEYPrivateKey *  key,
unsigned char *  output,
unsigned int output_len,
unsigned int  max_output_len,
unsigned char *  input,
unsigned int  input_len 
)

Definition at line 883 of file rsawrapr.c.

{
    SECStatus     rv;
    unsigned int  modulus_len = nsslowkey_PrivateModulusLen(key);

    if (modulus_len <= 0) 
       goto failure;
    if (modulus_len > max_output_len) 
       goto failure;
    PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
    if (key->keyType != NSSLOWKEYRSAKey)
       goto failure;
    if (input_len != modulus_len) 
       goto failure;

    rv = RSA_PrivateKeyOp(&key->u.rsa, output, input);
    if (rv != SECSuccess) {
       if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
           sftk_fatalError = PR_TRUE;
       }
       goto failure;
    }

    *output_len = modulus_len;
    return SECSuccess;

failure:
    return SECFailure;
}

Here is the call graph for this function:

SECStatus RSA_EncryptBlock ( NSSLOWKEYPublicKey *  key,
unsigned char *  output,
unsigned int output_len,
unsigned int  max_output_len,
unsigned char *  input,
unsigned int  input_len 
)

Definition at line 622 of file rsawrapr.c.

{
    SECStatus     rv;
    unsigned int  modulus_len = nsslowkey_PublicModulusLen(key);
    SECItem       formatted;
    SECItem       unformatted;

    formatted.data = NULL;
    if (max_output_len < modulus_len) 
       goto failure;
    PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
    if (key->keyType != NSSLOWKEYRSAKey)
       goto failure;

    unformatted.len  = input_len;
    unformatted.data = input;
    formatted.data   = NULL;
    rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockPublic,
                      &unformatted);
    if (rv != SECSuccess) 
       goto failure;

    rv = RSA_PublicKeyOp(&key->u.rsa, output, formatted.data);
    if (rv != SECSuccess) 
       goto failure;

    PORT_ZFree(formatted.data, modulus_len);
    *output_len = modulus_len;
    return SECSuccess;

failure:
    if (formatted.data != NULL) 
       PORT_ZFree(formatted.data, modulus_len);
    return SECFailure;
}

Here is the call graph for this function:

SECStatus RSA_EncryptRaw ( NSSLOWKEYPublicKey *  key,
unsigned char *  output,
unsigned int output_len,
unsigned int  max_output_len,
unsigned char *  input,
unsigned int  input_len 
)

Definition at line 841 of file rsawrapr.c.

{
    SECStatus rv;
    unsigned int  modulus_len = nsslowkey_PublicModulusLen(key);
    SECItem       formatted;
    SECItem       unformatted;

    formatted.data = NULL;
    if (max_output_len < modulus_len) 
       goto failure;
    PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
    if (key->keyType != NSSLOWKEYRSAKey)
       goto failure;

    unformatted.len  = input_len;
    unformatted.data = input;
    formatted.data   = NULL;
    rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockRaw, &unformatted);
    if (rv != SECSuccess)
       goto failure;

    rv = RSA_PublicKeyOp(&key->u.rsa, output, formatted.data);
    if (rv != SECSuccess) 
       goto failure;

    PORT_ZFree(formatted.data, modulus_len);
    *output_len = modulus_len;
    return SECSuccess;

failure:
    if (formatted.data != NULL) 
       PORT_ZFree(formatted.data, modulus_len);
    return SECFailure;
}

Here is the call graph for this function:

static SECStatus rsa_FormatBlock ( SECItem *  result,
unsigned  modulusLen,
RSA_BlockType  blockType,
SECItem *  data 
) [static]

Definition at line 373 of file rsawrapr.c.

{
    /*
     * XXX For now assume that the data length fits in a single
     * XXX encryption block; the ASSERTs below force this.
     * XXX To fix it, each case will have to loop over chunks whose
     * XXX lengths satisfy the assertions, until all data is handled.
     * XXX (Unless RSA has more to say about how to handle data
     * XXX which does not fit in a single encryption block?)
     * XXX And I do not know what the result is supposed to be,
     * XXX so the interface to this function may need to change
     * XXX to allow for returning multiple blocks, if they are
     * XXX not wanted simply concatenated one after the other.
     */

    switch (blockType) {
      case RSA_BlockPrivate0:
      case RSA_BlockPrivate:
      case RSA_BlockPublic:
       /*
        * 0x00 || BT || Pad || 0x00 || ActualData
        *
        * The "3" below is the first octet + the second octet + the 0x00
        * octet that always comes just before the ActualData.
        */
       PORT_Assert (data->len <= (modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN)));

       result->data = rsa_FormatOneBlock(modulusLen, blockType, data);
       if (result->data == NULL) {
           result->len = 0;
           return SECFailure;
       }
       result->len = modulusLen;

       break;

      case RSA_BlockOAEP:
       /*
        * 0x00 || BT || M1(Salt) || M2(Pad1||ActualData[||Pad2])
        *
        * The "2" below is the first octet + the second octet.
        * (The other fields do not contain the clear values, but are
        * the same length as the clear values.)
        */
       PORT_Assert (data->len <= (modulusLen - (2 + OAEP_SALT_LEN
                                           + OAEP_PAD_LEN)));

       result->data = rsa_FormatOneBlock(modulusLen, blockType, data);
       if (result->data == NULL) {
           result->len = 0;
           return SECFailure;
       }
       result->len = modulusLen;

       break;

      case RSA_BlockRaw:
       /*
        * Pad || ActualData
        * Pad is zeros. The application is responsible for recovering
        * the actual data.
        */
       if (data->len > modulusLen ) {
           return SECFailure;
       }
       result->data = (unsigned char*)PORT_ZAlloc(modulusLen);
       result->len = modulusLen;
       PORT_Memcpy(result->data+(modulusLen-data->len),data->data,data->len);
       break;

      default:
       PORT_Assert (0);
       result->data = NULL;
       result->len = 0;
       return SECFailure;
    }

    return SECSuccess;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static unsigned char* rsa_FormatOneBlock ( unsigned  modulusLen,
RSA_BlockType  blockType,
SECItem *  data 
) [static]

Definition at line 189 of file rsawrapr.c.

{
    unsigned char *block;
    unsigned char *bp;
    int padLen;
    int i;
    SECStatus rv;

    block = (unsigned char *) PORT_Alloc(modulusLen);
    if (block == NULL)
       return NULL;

    bp = block;

    /*
     * All RSA blocks start with two octets:
     * 0x00 || BlockType
     */
    *bp++ = RSA_BLOCK_FIRST_OCTET;
    *bp++ = (unsigned char) blockType;

    switch (blockType) {

      /*
       * Blocks intended for private-key operation.
       */
      case RSA_BlockPrivate0: /* essentially unused */
      case RSA_BlockPrivate:        /* preferred method */
       /*
        * 0x00 || BT || Pad || 0x00 || ActualData
        *   1      1   padLen    1      data->len
        * Pad is either all 0x00 or all 0xff bytes, depending on blockType.
        */
       padLen = modulusLen - data->len - 3;
       PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN);
       if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
           PORT_Free (block);
           return NULL;
       }
       PORT_Memset (bp,
                 blockType == RSA_BlockPrivate0
                     ? RSA_BLOCK_PRIVATE0_PAD_OCTET
                     : RSA_BLOCK_PRIVATE_PAD_OCTET,
                 padLen);
       bp += padLen;
       *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
       PORT_Memcpy (bp, data->data, data->len);
       break;

      /*
       * Blocks intended for public-key operation.
       */
      case RSA_BlockPublic:

       /*
        * 0x00 || BT || Pad || 0x00 || ActualData
        *   1      1   padLen    1      data->len
        * Pad is all non-zero random bytes.
        */
       padLen = modulusLen - data->len - 3;
       PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN);
       if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
           PORT_Free (block);
           return NULL;
       }
       for (i = 0; i < padLen; i++) {
           /* Pad with non-zero random data. */
           do {
              rv = RNG_GenerateGlobalRandomBytes(bp + i, 1);
           } while (rv == SECSuccess && bp[i] == RSA_BLOCK_AFTER_PAD_OCTET);
           if (rv != SECSuccess) {
              sftk_fatalError = PR_TRUE;
              PORT_Free (block);
              return NULL;
           }
       }
       bp += padLen;
       *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
       PORT_Memcpy (bp, data->data, data->len);

       break;

      /*
       * Blocks intended for public-key operation, using
       * Optimal Asymmetric Encryption Padding (OAEP).
       */
      case RSA_BlockOAEP:
       /*
        * 0x00 || BT || Modified2(Salt) || Modified1(PaddedData)
        *   1      1     OAEP_SALT_LEN     OAEP_PAD_LEN + data->len [+ N]
        *
        * where:
        *   PaddedData is "Pad1 || ActualData [|| Pad2]"
        *   Salt is random data.
        *   Pad1 is all zeros.
        *   Pad2, if present, is random data.
        *   (The "modified" fields are all the same length as the original
        * unmodified values; they are just xor'd with other values.)
        *
        *   Modified1 is an XOR of PaddedData with a special octet
        * string constructed of iterated hashing of Salt (see below).
        *   Modified2 is an XOR of Salt with the low-order octets of
        * the hash of Modified1 (see farther below ;-).
        *
        * Whew!
        */


       /*
        * Salt
        */
       rv = RNG_GenerateGlobalRandomBytes(bp, OAEP_SALT_LEN);
       if (rv != SECSuccess) {
           sftk_fatalError = PR_TRUE;
           PORT_Free (block);
           return NULL;
       }
       bp += OAEP_SALT_LEN;

       /*
        * Pad1
        */
       PORT_Memset (bp, OAEP_PAD_OCTET, OAEP_PAD_LEN);
       bp += OAEP_PAD_LEN;

       /*
        * Data
        */
       PORT_Memcpy (bp, data->data, data->len);
       bp += data->len;

       /*
        * Pad2
        */
       if (bp < (block + modulusLen)) {
           rv = RNG_GenerateGlobalRandomBytes(bp, block - bp + modulusLen);
           if (rv != SECSuccess) {
              sftk_fatalError = PR_TRUE;
              PORT_Free (block);
              return NULL;
           }
       }

       /*
        * Now we have the following:
        * 0x00 || BT || Salt || PaddedData
        * (From this point on, "Pad1 || Data [|| Pad2]" is treated
        * as the one entity PaddedData.)
        *
        * We need to turn PaddedData into Modified1.
        */
       if (oaep_xor_with_h1(block + 2 + OAEP_SALT_LEN,
                          modulusLen - 2 - OAEP_SALT_LEN,
                          block + 2, OAEP_SALT_LEN) != SECSuccess) {
           PORT_Free (block);
           return NULL;
       }

       /*
        * Now we have:
        * 0x00 || BT || Salt || Modified1(PaddedData)
        *
        * The remaining task is to turn Salt into Modified2.
        */
       if (oaep_xor_with_h2(block + 2, OAEP_SALT_LEN,
                          block + 2 + OAEP_SALT_LEN,
                          modulusLen - 2 - OAEP_SALT_LEN) != SECSuccess) {
           PORT_Free (block);
           return NULL;
       }

       break;

      default:
       PORT_Assert (0);
       PORT_Free (block);
       return NULL;
    }

    return block;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus RSA_Sign ( NSSLOWKEYPrivateKey *  key,
unsigned char *  output,
unsigned int output_len,
unsigned int  maxOutputLen,
unsigned char *  input,
unsigned int  input_len 
)

Definition at line 456 of file rsawrapr.c.

{
    SECStatus     rv          = SECSuccess;
    unsigned int  modulus_len = nsslowkey_PrivateModulusLen(key);
    SECItem       formatted;
    SECItem       unformatted;

    if (maxOutputLen < modulus_len) 
       return SECFailure;
    PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
    if (key->keyType != NSSLOWKEYRSAKey)
       return SECFailure;

    unformatted.len  = input_len;
    unformatted.data = input;
    formatted.data   = NULL;
    rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockPrivate,
                      &unformatted);
    if (rv != SECSuccess) 
       goto done;

    rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, output, formatted.data);
    if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
       sftk_fatalError = PR_TRUE;
    }
    *output_len = modulus_len;

    goto done;

done:
    if (formatted.data != NULL) 
       PORT_ZFree(formatted.data, modulus_len);
    return rv;
}

Here is the call graph for this function:

SECStatus RSA_SignRaw ( NSSLOWKEYPrivateKey *  key,
unsigned char *  output,
unsigned int output_len,
unsigned int  maxOutputLen,
unsigned char *  input,
unsigned int  input_len 
)

Definition at line 726 of file rsawrapr.c.

{
    SECStatus    rv          = SECSuccess;
    unsigned int modulus_len = nsslowkey_PrivateModulusLen(key);
    SECItem      formatted;
    SECItem      unformatted;

    if (maxOutputLen < modulus_len) 
       return SECFailure;
    PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
    if (key->keyType != NSSLOWKEYRSAKey)
       return SECFailure;

    unformatted.len  = input_len;
    unformatted.data = input;
    formatted.data   = NULL;
    rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockRaw, &unformatted);
    if (rv != SECSuccess) 
       goto done;

    rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, output, formatted.data);
    if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
       sftk_fatalError = PR_TRUE;
    }
    *output_len = modulus_len;

done:
    if (formatted.data != NULL) 
       PORT_ZFree(formatted.data, modulus_len);
    return rv;
}

Here is the call graph for this function:

static SHA1Context* SHA1_CloneContext ( SHA1Context *  original) [static]

Definition at line 62 of file rsawrapr.c.

{
    SHA1Context *  clone    = NULL;
    unsigned char *pBuf;
    int            sha1ContextSize = SHA1_FlattenSize(original);
    SECStatus      frv;
    unsigned char  buf[FLAT_BUFSIZE];

    PORT_Assert(sizeof buf >= sha1ContextSize);
    if (sizeof buf >= sha1ContextSize) {
       pBuf = buf;
    } else {
        pBuf = PORT_Alloc(sha1ContextSize);
       if (!pBuf)
           goto done;
    }

    frv = SHA1_Flatten(original, pBuf);
    if (frv == SECSuccess) {
       clone = SHA1_Resurrect(pBuf, NULL);
       memset(pBuf, 0, sha1ContextSize);
    }
done:
    if (pBuf != buf)
       PORT_Free(pBuf);
    return clone;
}

Here is the call graph for this function:

Here is the caller graph for this function: