Thu, 22 Jan 2015 13:21:57 +0100
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 | } |