1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/softoken/sftkhmac.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,192 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include "seccomon.h" 1.9 +#include "secerr.h" 1.10 +#include "blapi.h" 1.11 +#include "pkcs11i.h" 1.12 +#include "softoken.h" 1.13 +#include "hmacct.h" 1.14 + 1.15 +/* MACMechanismToHash converts a PKCS#11 MAC mechanism into a freebl hash 1.16 + * type. */ 1.17 +static HASH_HashType 1.18 +MACMechanismToHash(CK_MECHANISM_TYPE mech) 1.19 +{ 1.20 + switch (mech) { 1.21 + case CKM_MD5_HMAC: 1.22 + case CKM_SSL3_MD5_MAC: 1.23 + return HASH_AlgMD5; 1.24 + case CKM_SHA_1_HMAC: 1.25 + case CKM_SSL3_SHA1_MAC: 1.26 + return HASH_AlgSHA1; 1.27 + case CKM_SHA224_HMAC: 1.28 + return HASH_AlgSHA224; 1.29 + case CKM_SHA256_HMAC: 1.30 + return HASH_AlgSHA256; 1.31 + case CKM_SHA384_HMAC: 1.32 + return HASH_AlgSHA384; 1.33 + case CKM_SHA512_HMAC: 1.34 + return HASH_AlgSHA512; 1.35 + } 1.36 + return HASH_AlgNULL; 1.37 +} 1.38 + 1.39 +static sftk_MACConstantTimeCtx * 1.40 +SetupMAC(CK_MECHANISM_PTR mech, SFTKObject *key) 1.41 +{ 1.42 + CK_NSS_MAC_CONSTANT_TIME_PARAMS *params = 1.43 + (CK_NSS_MAC_CONSTANT_TIME_PARAMS *) mech->pParameter; 1.44 + sftk_MACConstantTimeCtx *ctx; 1.45 + HASH_HashType alg; 1.46 + SFTKAttribute *keyval; 1.47 + unsigned char secret[sizeof(ctx->secret)]; 1.48 + unsigned int secretLength; 1.49 + 1.50 + if (mech->ulParameterLen != sizeof(CK_NSS_MAC_CONSTANT_TIME_PARAMS)) { 1.51 + return NULL; 1.52 + } 1.53 + 1.54 + alg = MACMechanismToHash(params->macAlg); 1.55 + if (alg == HASH_AlgNULL) { 1.56 + return NULL; 1.57 + } 1.58 + 1.59 + keyval = sftk_FindAttribute(key,CKA_VALUE); 1.60 + if (keyval == NULL) { 1.61 + return NULL; 1.62 + } 1.63 + secretLength = keyval->attrib.ulValueLen; 1.64 + if (secretLength > sizeof(secret)) { 1.65 + sftk_FreeAttribute(keyval); 1.66 + return NULL; 1.67 + } 1.68 + memcpy(secret, keyval->attrib.pValue, secretLength); 1.69 + sftk_FreeAttribute(keyval); 1.70 + 1.71 + ctx = PORT_Alloc(sizeof(sftk_MACConstantTimeCtx)); 1.72 + if (!ctx) { 1.73 + return NULL; 1.74 + } 1.75 + 1.76 + memcpy(ctx->secret, secret, secretLength); 1.77 + ctx->secretLength = secretLength; 1.78 + ctx->hash = HASH_GetRawHashObject(alg); 1.79 + ctx->totalLength = params->ulBodyTotalLen; 1.80 + 1.81 + return ctx; 1.82 +} 1.83 + 1.84 +sftk_MACConstantTimeCtx * 1.85 +sftk_HMACConstantTime_New(CK_MECHANISM_PTR mech, SFTKObject *key) 1.86 +{ 1.87 + CK_NSS_MAC_CONSTANT_TIME_PARAMS *params = 1.88 + (CK_NSS_MAC_CONSTANT_TIME_PARAMS *) mech->pParameter; 1.89 + sftk_MACConstantTimeCtx *ctx; 1.90 + 1.91 + if (params->ulHeaderLen > sizeof(ctx->header)) { 1.92 + return NULL; 1.93 + } 1.94 + ctx = SetupMAC(mech, key); 1.95 + if (!ctx) { 1.96 + return NULL; 1.97 + } 1.98 + 1.99 + ctx->headerLength = params->ulHeaderLen; 1.100 + memcpy(ctx->header, params->pHeader, params->ulHeaderLen); 1.101 + return ctx; 1.102 +} 1.103 + 1.104 +sftk_MACConstantTimeCtx * 1.105 +sftk_SSLv3MACConstantTime_New(CK_MECHANISM_PTR mech, SFTKObject *key) 1.106 +{ 1.107 + CK_NSS_MAC_CONSTANT_TIME_PARAMS *params = 1.108 + (CK_NSS_MAC_CONSTANT_TIME_PARAMS *) mech->pParameter; 1.109 + unsigned int padLength = 40, j; 1.110 + sftk_MACConstantTimeCtx *ctx; 1.111 + 1.112 + if (params->macAlg != CKM_SSL3_MD5_MAC && 1.113 + params->macAlg != CKM_SSL3_SHA1_MAC) { 1.114 + return NULL; 1.115 + } 1.116 + ctx = SetupMAC(mech, key); 1.117 + if (!ctx) { 1.118 + return NULL; 1.119 + } 1.120 + 1.121 + if (params->macAlg == CKM_SSL3_MD5_MAC) { 1.122 + padLength = 48; 1.123 + } 1.124 + 1.125 + ctx->headerLength = 1.126 + ctx->secretLength + 1.127 + padLength + 1.128 + params->ulHeaderLen; 1.129 + 1.130 + if (ctx->headerLength > sizeof(ctx->header)) { 1.131 + goto loser; 1.132 + } 1.133 + 1.134 + j = 0; 1.135 + memcpy(&ctx->header[j], ctx->secret, ctx->secretLength); 1.136 + j += ctx->secretLength; 1.137 + memset(&ctx->header[j], 0x36, padLength); 1.138 + j += padLength; 1.139 + memcpy(&ctx->header[j], params->pHeader, params->ulHeaderLen); 1.140 + 1.141 + return ctx; 1.142 + 1.143 +loser: 1.144 + PORT_Free(ctx); 1.145 + return NULL; 1.146 +} 1.147 + 1.148 +void 1.149 +sftk_HMACConstantTime_Update(void *pctx, void *data, unsigned int len) 1.150 +{ 1.151 + sftk_MACConstantTimeCtx *ctx = (sftk_MACConstantTimeCtx *) pctx; 1.152 + SECStatus rv = HMAC_ConstantTime( 1.153 + ctx->mac, NULL, sizeof(ctx->mac), 1.154 + ctx->hash, 1.155 + ctx->secret, ctx->secretLength, 1.156 + ctx->header, ctx->headerLength, 1.157 + data, len, 1.158 + ctx->totalLength); 1.159 + PORT_Assert(rv == SECSuccess); 1.160 +} 1.161 + 1.162 +void 1.163 +sftk_SSLv3MACConstantTime_Update(void *pctx, void *data, unsigned int len) 1.164 +{ 1.165 + sftk_MACConstantTimeCtx *ctx = (sftk_MACConstantTimeCtx *) pctx; 1.166 + SECStatus rv = SSLv3_MAC_ConstantTime( 1.167 + ctx->mac, NULL, sizeof(ctx->mac), 1.168 + ctx->hash, 1.169 + ctx->secret, ctx->secretLength, 1.170 + ctx->header, ctx->headerLength, 1.171 + data, len, 1.172 + ctx->totalLength); 1.173 + PORT_Assert(rv == SECSuccess); 1.174 +} 1.175 + 1.176 +void 1.177 +sftk_MACConstantTime_EndHash(void *pctx, void *out, unsigned int *outLength, 1.178 + unsigned int maxLength) 1.179 +{ 1.180 + const sftk_MACConstantTimeCtx *ctx = (sftk_MACConstantTimeCtx *) pctx; 1.181 + unsigned int toCopy = ctx->hash->length; 1.182 + if (toCopy > maxLength) { 1.183 + toCopy = maxLength; 1.184 + } 1.185 + memcpy(out, ctx->mac, toCopy); 1.186 + if (outLength) { 1.187 + *outLength = toCopy; 1.188 + } 1.189 +} 1.190 + 1.191 +void 1.192 +sftk_MACConstantTime_DestroyContext(void *pctx, PRBool free) 1.193 +{ 1.194 + PORT_Free(pctx); 1.195 +}