security/nss/lib/softoken/sftkhmac.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #include "seccomon.h"
michael@0 6 #include "secerr.h"
michael@0 7 #include "blapi.h"
michael@0 8 #include "pkcs11i.h"
michael@0 9 #include "softoken.h"
michael@0 10 #include "hmacct.h"
michael@0 11
michael@0 12 /* MACMechanismToHash converts a PKCS#11 MAC mechanism into a freebl hash
michael@0 13 * type. */
michael@0 14 static HASH_HashType
michael@0 15 MACMechanismToHash(CK_MECHANISM_TYPE mech)
michael@0 16 {
michael@0 17 switch (mech) {
michael@0 18 case CKM_MD5_HMAC:
michael@0 19 case CKM_SSL3_MD5_MAC:
michael@0 20 return HASH_AlgMD5;
michael@0 21 case CKM_SHA_1_HMAC:
michael@0 22 case CKM_SSL3_SHA1_MAC:
michael@0 23 return HASH_AlgSHA1;
michael@0 24 case CKM_SHA224_HMAC:
michael@0 25 return HASH_AlgSHA224;
michael@0 26 case CKM_SHA256_HMAC:
michael@0 27 return HASH_AlgSHA256;
michael@0 28 case CKM_SHA384_HMAC:
michael@0 29 return HASH_AlgSHA384;
michael@0 30 case CKM_SHA512_HMAC:
michael@0 31 return HASH_AlgSHA512;
michael@0 32 }
michael@0 33 return HASH_AlgNULL;
michael@0 34 }
michael@0 35
michael@0 36 static sftk_MACConstantTimeCtx *
michael@0 37 SetupMAC(CK_MECHANISM_PTR mech, SFTKObject *key)
michael@0 38 {
michael@0 39 CK_NSS_MAC_CONSTANT_TIME_PARAMS *params =
michael@0 40 (CK_NSS_MAC_CONSTANT_TIME_PARAMS *) mech->pParameter;
michael@0 41 sftk_MACConstantTimeCtx *ctx;
michael@0 42 HASH_HashType alg;
michael@0 43 SFTKAttribute *keyval;
michael@0 44 unsigned char secret[sizeof(ctx->secret)];
michael@0 45 unsigned int secretLength;
michael@0 46
michael@0 47 if (mech->ulParameterLen != sizeof(CK_NSS_MAC_CONSTANT_TIME_PARAMS)) {
michael@0 48 return NULL;
michael@0 49 }
michael@0 50
michael@0 51 alg = MACMechanismToHash(params->macAlg);
michael@0 52 if (alg == HASH_AlgNULL) {
michael@0 53 return NULL;
michael@0 54 }
michael@0 55
michael@0 56 keyval = sftk_FindAttribute(key,CKA_VALUE);
michael@0 57 if (keyval == NULL) {
michael@0 58 return NULL;
michael@0 59 }
michael@0 60 secretLength = keyval->attrib.ulValueLen;
michael@0 61 if (secretLength > sizeof(secret)) {
michael@0 62 sftk_FreeAttribute(keyval);
michael@0 63 return NULL;
michael@0 64 }
michael@0 65 memcpy(secret, keyval->attrib.pValue, secretLength);
michael@0 66 sftk_FreeAttribute(keyval);
michael@0 67
michael@0 68 ctx = PORT_Alloc(sizeof(sftk_MACConstantTimeCtx));
michael@0 69 if (!ctx) {
michael@0 70 return NULL;
michael@0 71 }
michael@0 72
michael@0 73 memcpy(ctx->secret, secret, secretLength);
michael@0 74 ctx->secretLength = secretLength;
michael@0 75 ctx->hash = HASH_GetRawHashObject(alg);
michael@0 76 ctx->totalLength = params->ulBodyTotalLen;
michael@0 77
michael@0 78 return ctx;
michael@0 79 }
michael@0 80
michael@0 81 sftk_MACConstantTimeCtx *
michael@0 82 sftk_HMACConstantTime_New(CK_MECHANISM_PTR mech, SFTKObject *key)
michael@0 83 {
michael@0 84 CK_NSS_MAC_CONSTANT_TIME_PARAMS *params =
michael@0 85 (CK_NSS_MAC_CONSTANT_TIME_PARAMS *) mech->pParameter;
michael@0 86 sftk_MACConstantTimeCtx *ctx;
michael@0 87
michael@0 88 if (params->ulHeaderLen > sizeof(ctx->header)) {
michael@0 89 return NULL;
michael@0 90 }
michael@0 91 ctx = SetupMAC(mech, key);
michael@0 92 if (!ctx) {
michael@0 93 return NULL;
michael@0 94 }
michael@0 95
michael@0 96 ctx->headerLength = params->ulHeaderLen;
michael@0 97 memcpy(ctx->header, params->pHeader, params->ulHeaderLen);
michael@0 98 return ctx;
michael@0 99 }
michael@0 100
michael@0 101 sftk_MACConstantTimeCtx *
michael@0 102 sftk_SSLv3MACConstantTime_New(CK_MECHANISM_PTR mech, SFTKObject *key)
michael@0 103 {
michael@0 104 CK_NSS_MAC_CONSTANT_TIME_PARAMS *params =
michael@0 105 (CK_NSS_MAC_CONSTANT_TIME_PARAMS *) mech->pParameter;
michael@0 106 unsigned int padLength = 40, j;
michael@0 107 sftk_MACConstantTimeCtx *ctx;
michael@0 108
michael@0 109 if (params->macAlg != CKM_SSL3_MD5_MAC &&
michael@0 110 params->macAlg != CKM_SSL3_SHA1_MAC) {
michael@0 111 return NULL;
michael@0 112 }
michael@0 113 ctx = SetupMAC(mech, key);
michael@0 114 if (!ctx) {
michael@0 115 return NULL;
michael@0 116 }
michael@0 117
michael@0 118 if (params->macAlg == CKM_SSL3_MD5_MAC) {
michael@0 119 padLength = 48;
michael@0 120 }
michael@0 121
michael@0 122 ctx->headerLength =
michael@0 123 ctx->secretLength +
michael@0 124 padLength +
michael@0 125 params->ulHeaderLen;
michael@0 126
michael@0 127 if (ctx->headerLength > sizeof(ctx->header)) {
michael@0 128 goto loser;
michael@0 129 }
michael@0 130
michael@0 131 j = 0;
michael@0 132 memcpy(&ctx->header[j], ctx->secret, ctx->secretLength);
michael@0 133 j += ctx->secretLength;
michael@0 134 memset(&ctx->header[j], 0x36, padLength);
michael@0 135 j += padLength;
michael@0 136 memcpy(&ctx->header[j], params->pHeader, params->ulHeaderLen);
michael@0 137
michael@0 138 return ctx;
michael@0 139
michael@0 140 loser:
michael@0 141 PORT_Free(ctx);
michael@0 142 return NULL;
michael@0 143 }
michael@0 144
michael@0 145 void
michael@0 146 sftk_HMACConstantTime_Update(void *pctx, void *data, unsigned int len)
michael@0 147 {
michael@0 148 sftk_MACConstantTimeCtx *ctx = (sftk_MACConstantTimeCtx *) pctx;
michael@0 149 SECStatus rv = HMAC_ConstantTime(
michael@0 150 ctx->mac, NULL, sizeof(ctx->mac),
michael@0 151 ctx->hash,
michael@0 152 ctx->secret, ctx->secretLength,
michael@0 153 ctx->header, ctx->headerLength,
michael@0 154 data, len,
michael@0 155 ctx->totalLength);
michael@0 156 PORT_Assert(rv == SECSuccess);
michael@0 157 }
michael@0 158
michael@0 159 void
michael@0 160 sftk_SSLv3MACConstantTime_Update(void *pctx, void *data, unsigned int len)
michael@0 161 {
michael@0 162 sftk_MACConstantTimeCtx *ctx = (sftk_MACConstantTimeCtx *) pctx;
michael@0 163 SECStatus rv = SSLv3_MAC_ConstantTime(
michael@0 164 ctx->mac, NULL, sizeof(ctx->mac),
michael@0 165 ctx->hash,
michael@0 166 ctx->secret, ctx->secretLength,
michael@0 167 ctx->header, ctx->headerLength,
michael@0 168 data, len,
michael@0 169 ctx->totalLength);
michael@0 170 PORT_Assert(rv == SECSuccess);
michael@0 171 }
michael@0 172
michael@0 173 void
michael@0 174 sftk_MACConstantTime_EndHash(void *pctx, void *out, unsigned int *outLength,
michael@0 175 unsigned int maxLength)
michael@0 176 {
michael@0 177 const sftk_MACConstantTimeCtx *ctx = (sftk_MACConstantTimeCtx *) pctx;
michael@0 178 unsigned int toCopy = ctx->hash->length;
michael@0 179 if (toCopy > maxLength) {
michael@0 180 toCopy = maxLength;
michael@0 181 }
michael@0 182 memcpy(out, ctx->mac, toCopy);
michael@0 183 if (outLength) {
michael@0 184 *outLength = toCopy;
michael@0 185 }
michael@0 186 }
michael@0 187
michael@0 188 void
michael@0 189 sftk_MACConstantTime_DestroyContext(void *pctx, PRBool free)
michael@0 190 {
michael@0 191 PORT_Free(pctx);
michael@0 192 }

mercurial