예제 #1
0
SECStatus intel_AES_GCM_DecryptUpdate(intel_AES_GCMContext *gcm, 
            unsigned char *outbuf,
            unsigned int *outlen, unsigned int maxout,
            const unsigned char *inbuf, unsigned int inlen,
            unsigned int blocksize)
{
    unsigned int tagBytes;
    unsigned char T[AES_BLOCK_SIZE];
    const unsigned char *intag;

    tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE-1)) / PR_BITS_PER_BYTE;
 
    /* get the authentication block */
    if (inlen < tagBytes) {
        PORT_SetError(SEC_ERROR_INPUT_LEN);
        return SECFailure;
    }

    inlen -= tagBytes;
    intag = inbuf + inlen;

    if (maxout < inlen) {
        *outlen = inlen;
        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
        return SECFailure;
    }

    intel_aes_gcmDEC(
         inbuf,
         outbuf,
         gcm,
         inlen);

    gcm->Mlen += inlen;
    intel_aes_gcmTAG(
         gcm->Htbl,
         gcm->T,
         gcm->Mlen,
         gcm->Alen,
         gcm->X0,
         T);

    if (NSS_SecureMemcmp(T, intag, tagBytes) != 0) {
        memset(outbuf, 0, inlen);
        *outlen = 0;
        /* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */
        PORT_SetError(SEC_ERROR_BAD_DATA);
        return SECFailure;
    }
    *outlen = inlen;

    return SECSuccess;
}
예제 #2
0
SECStatus
ChaCha20Poly1305_Open(const ChaCha20Poly1305Context *ctx,
		      unsigned char *output, unsigned int *outputLen,
		      unsigned int maxOutputLen,
		      const unsigned char *input, unsigned int inputLen,
		      const unsigned char *nonce, unsigned int nonceLen,
		      const unsigned char *ad, unsigned int adLen)
{
    unsigned char block[64];
    unsigned char tag[16];

    if (nonceLen != 8) {
	PORT_SetError(SEC_ERROR_INPUT_LEN);
	return SECFailure;
    }
    if (inputLen < ctx->tagLen) {
	PORT_SetError(SEC_ERROR_INPUT_LEN);
	return SECFailure;
    }
    *outputLen = inputLen - ctx->tagLen;
    if (maxOutputLen < *outputLen) {
	PORT_SetError(SEC_ERROR_OUTPUT_LEN);
	return SECFailure;
    }

    memset(block, 0, sizeof(block));
    // Generate a block of keystream. The first 32 bytes will be the poly1305
    // key. The remainder of the block is discarded.
    ChaCha20XOR(block, block, sizeof(block), ctx->key, nonce, 0);
    Poly1305Do(tag, ad, adLen, input, inputLen - ctx->tagLen, block);
    if (NSS_SecureMemcmp(tag, &input[inputLen - ctx->tagLen], ctx->tagLen) != 0) {
	PORT_SetError(SEC_ERROR_BAD_DATA);
	return SECFailure;
    }

    ChaCha20XOR(output, input, inputLen - ctx->tagLen, ctx->key, nonce, 1);

    return SECSuccess;
}
예제 #3
0
SECStatus
ssl_SelfEncryptUnprotectInt(
    PK11SymKey *encKey, PK11SymKey *macKey, const unsigned char *keyName,
    const PRUint8 *in, unsigned int inLen,
    PRUint8 *out, unsigned int *outLen, unsigned int maxOutLen)
{
    sslReader reader = SSL_READER(in, inLen);

    sslReadBuffer encodedKeyNameBuffer = { 0 };
    SECStatus rv = sslRead_Read(&reader, SELF_ENCRYPT_KEY_NAME_LEN,
                                &encodedKeyNameBuffer);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    sslReadBuffer ivBuffer = { 0 };
    rv = sslRead_Read(&reader, AES_BLOCK_SIZE, &ivBuffer);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    PRUint64 cipherTextLen = 0;
    rv = sslRead_ReadNumber(&reader, 2, &cipherTextLen);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    sslReadBuffer cipherTextBuffer = { 0 };
    rv = sslRead_Read(&reader, (unsigned int)cipherTextLen, &cipherTextBuffer);
    if (rv != SECSuccess) {
        return SECFailure;
    }
    unsigned int bytesToMac = reader.offset;

    sslReadBuffer encodedMacBuffer = { 0 };
    rv = sslRead_Read(&reader, SHA256_LENGTH, &encodedMacBuffer);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    /* Make sure we're at the end of the block. */
    if (reader.offset != reader.buf.len) {
        PORT_SetError(SEC_ERROR_BAD_DATA);
        return SECFailure;
    }

    /* Now that everything is decoded, we can make progress. */
    /* 1. Check that we have the right key. */
    if (PORT_Memcmp(keyName, encodedKeyNameBuffer.buf, SELF_ENCRYPT_KEY_NAME_LEN)) {
        PORT_SetError(SEC_ERROR_NOT_A_RECIPIENT);
        return SECFailure;
    }

    /* 2. Check the MAC */
    unsigned char computedMac[SHA256_LENGTH];
    unsigned int computedMacLen = 0;
    rv = ssl_MacBuffer(macKey, CKM_SHA256_HMAC, in, bytesToMac,
                       computedMac, &computedMacLen, sizeof(computedMac));
    if (rv != SECSuccess) {
        return SECFailure;
    }
    PORT_Assert(computedMacLen == SHA256_LENGTH);
    if (NSS_SecureMemcmp(computedMac, encodedMacBuffer.buf, computedMacLen) != 0) {
        PORT_SetError(SEC_ERROR_BAD_DATA);
        return SECFailure;
    }

    /* 3. OK, it verifies, now decrypt. */
    SECItem ivItem = { siBuffer, (unsigned char *)ivBuffer.buf, AES_BLOCK_SIZE };
    rv = PK11_Decrypt(encKey, CKM_AES_CBC_PAD, &ivItem,
                      out, outLen, maxOutLen, cipherTextBuffer.buf, cipherTextLen);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    return SECSuccess;
}
예제 #4
0
/*
 * point validation is not necessary in general. But this checks a point (px)
 * against some known bad values.
 */
SECStatus
ec_Curve25519_pt_validate(const SECItem *px)
{
    PRUint8 *p;
    int i;
    PRUint8 forbiddenValues[12][32] = {
        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
        { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
        { 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae,
          0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a,
          0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd,
          0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 },
        { 0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24,
          0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b,
          0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86,
          0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57 },
        { 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
        { 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
        { 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
        { 0xcd, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae,
          0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a,
          0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd,
          0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x80 },
        { 0x4c, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24,
          0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b,
          0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86,
          0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0xd7 },
        { 0xd9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
        { 0xda, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
        { 0xdb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
    };

    if (px->len == 32) {
        p = px->data;
    } else {
        return SECFailure;
    }

    for (i = 0; i < PR_ARRAY_SIZE(forbiddenValues); ++i) {
        if (NSS_SecureMemcmp(p, forbiddenValues[i], px->len) == 0) {
            return SECFailure;
        }
    }

    return SECSuccess;
}