OLD | NEW |
1 /* tlsprf.c - TLS Pseudo Random Function (PRF) implementation | 1 /* tlsprf.c - TLS Pseudo Random Function (PRF) implementation |
2 * | 2 * |
3 * This Source Code Form is subject to the terms of the Mozilla Public | 3 * This Source Code Form is subject to the terms of the Mozilla Public |
4 * License, v. 2.0. If a copy of the MPL was not distributed with this | 4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | 6 |
7 #include "pkcs11i.h" | 7 #include "pkcs11i.h" |
8 #include "blapi.h" | 8 #include "blapi.h" |
| 9 #include "secerr.h" |
9 | 10 |
10 #define SFTK_OFFSETOF(str, memb) ((PRPtrdiff)(&(((str *)0)->memb))) | 11 #define SFTK_OFFSETOF(str, memb) ((PRPtrdiff)(&(((str *)0)->memb))) |
11 | 12 |
12 static void sftk_TLSPRFNull(void *data, PRBool freeit) | 13 static void sftk_TLSPRFNull(void *data, PRBool freeit) |
13 { | 14 { |
14 return; | 15 return; |
15 } | 16 } |
16 | 17 |
17 typedef struct { | 18 typedef struct { |
18 PRUint32 cxSize; /* size of allocated block, in bytes. */ | 19 PRUint32 cxSize; /* size of allocated block, in bytes. */ |
19 PRUint32 cxBufSize; /* sizeof buffer at cxBufPtr. */ | 20 PRUint32 cxBufSize; /* sizeof buffer at cxBufPtr. */ |
20 unsigned char *cxBufPtr; /* points to real buffer, may be cxBuf. */ | 21 unsigned char *cxBufPtr; /* points to real buffer, may be cxBuf. */ |
21 PRUint32 cxKeyLen; /* bytes of cxBufPtr containing key. */ | 22 PRUint32 cxKeyLen; /* bytes of cxBufPtr containing key. */ |
22 PRUint32 cxDataLen; /* bytes of cxBufPtr containing data. */ | 23 PRUint32 cxDataLen; /* bytes of cxBufPtr containing data. */ |
23 SECStatus cxRv; /* records failure of void functions. */ | 24 SECStatus cxRv; /* records failure of void functions. */ |
24 PRBool cxIsFIPS; /* true if conforming to FIPS 198. */ | 25 PRBool cxIsFIPS; /* true if conforming to FIPS 198. */ |
25 HASH_HashType cxHashAlg; /* hash algorithm to use for TLS 1.2+ */ | 26 HASH_HashType cxHashAlg; /* hash algorithm to use for TLS 1.2+ */ |
| 27 unsigned int cxOutLen; /* bytes of output if nonzero */ |
26 unsigned char cxBuf[512]; /* actual size may be larger than 512. */ | 28 unsigned char cxBuf[512]; /* actual size may be larger than 512. */ |
27 } TLSPRFContext; | 29 } TLSPRFContext; |
28 | 30 |
29 static void | 31 static void |
30 sftk_TLSPRFHashUpdate(TLSPRFContext *cx, const unsigned char *data, | 32 sftk_TLSPRFHashUpdate(TLSPRFContext *cx, const unsigned char *data, |
31 unsigned int data_len) | 33 unsigned int data_len) |
32 { | 34 { |
33 PRUint32 bytesUsed = cx->cxKeyLen + cx->cxDataLen; | 35 PRUint32 bytesUsed = cx->cxKeyLen + cx->cxDataLen; |
34 | 36 |
35 if (cx->cxRv != SECSuccess) /* function has previously failed. */ | 37 if (cx->cxRv != SECSuccess) /* function has previously failed. */ |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 if (cx->cxRv != SECSuccess) | 82 if (cx->cxRv != SECSuccess) |
81 return cx->cxRv; | 83 return cx->cxRv; |
82 | 84 |
83 secretItem.data = cx->cxBufPtr; | 85 secretItem.data = cx->cxBufPtr; |
84 secretItem.len = cx->cxKeyLen; | 86 secretItem.len = cx->cxKeyLen; |
85 | 87 |
86 seedItem.data = cx->cxBufPtr + cx->cxKeyLen; | 88 seedItem.data = cx->cxBufPtr + cx->cxKeyLen; |
87 seedItem.len = cx->cxDataLen; | 89 seedItem.len = cx->cxDataLen; |
88 | 90 |
89 sigItem.data = sig; | 91 sigItem.data = sig; |
90 sigItem.len = maxLen; | 92 if (cx->cxOutLen == 0) { |
| 93 » sigItem.len = maxLen; |
| 94 } else if (cx->cxOutLen <= maxLen) { |
| 95 » sigItem.len = cx->cxOutLen; |
| 96 } else { |
| 97 » PORT_SetError(SEC_ERROR_OUTPUT_LEN); |
| 98 » return SECFailure; |
| 99 } |
91 | 100 |
92 if (cx->cxHashAlg != HASH_AlgNULL) { | 101 if (cx->cxHashAlg != HASH_AlgNULL) { |
93 rv = TLS_P_hash(cx->cxHashAlg, &secretItem, NULL, &seedItem, &sigItem, | 102 rv = TLS_P_hash(cx->cxHashAlg, &secretItem, NULL, &seedItem, &sigItem, |
94 cx->cxIsFIPS); | 103 cx->cxIsFIPS); |
95 } else { | 104 } else { |
96 rv = TLS_PRF(&secretItem, NULL, &seedItem, &sigItem, cx->cxIsFIPS); | 105 rv = TLS_PRF(&secretItem, NULL, &seedItem, &sigItem, cx->cxIsFIPS); |
97 } | 106 } |
98 if (rv == SECSuccess && sigLen != NULL) | 107 if (rv == SECSuccess && sigLen != NULL) |
99 *sigLen = sigItem.len; | 108 *sigLen = sigItem.len; |
100 return rv; | 109 return rv; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 if (cx->cxBufPtr != cx->cxBuf) | 144 if (cx->cxBufPtr != cx->cxBuf) |
136 PORT_ZFree(cx->cxBufPtr, cx->cxBufSize); | 145 PORT_ZFree(cx->cxBufPtr, cx->cxBufSize); |
137 PORT_ZFree(cx, cx->cxSize); | 146 PORT_ZFree(cx, cx->cxSize); |
138 } | 147 } |
139 } | 148 } |
140 | 149 |
141 CK_RV | 150 CK_RV |
142 sftk_TLSPRFInit(SFTKSessionContext *context, | 151 sftk_TLSPRFInit(SFTKSessionContext *context, |
143 SFTKObject * key, | 152 SFTKObject * key, |
144 CK_KEY_TYPE key_type, | 153 CK_KEY_TYPE key_type, |
145 » » HASH_HashType hash_alg) | 154 » » HASH_HashType hash_alg, |
| 155 » » unsigned int out_len) |
146 { | 156 { |
147 SFTKAttribute * keyVal; | 157 SFTKAttribute * keyVal; |
148 TLSPRFContext * prf_cx; | 158 TLSPRFContext * prf_cx; |
149 CK_RV crv = CKR_HOST_MEMORY; | 159 CK_RV crv = CKR_HOST_MEMORY; |
150 PRUint32 keySize; | 160 PRUint32 keySize; |
151 PRUint32 blockSize; | 161 PRUint32 blockSize; |
152 | 162 |
153 if (key_type != CKK_GENERIC_SECRET) | 163 if (key_type != CKK_GENERIC_SECRET) |
154 return CKR_KEY_TYPE_INCONSISTENT; /* CKR_KEY_FUNCTION_NOT_PERMITTED */ | 164 return CKR_KEY_TYPE_INCONSISTENT; /* CKR_KEY_FUNCTION_NOT_PERMITTED */ |
155 | 165 |
156 context->multi = PR_TRUE; | 166 context->multi = PR_TRUE; |
157 | 167 |
158 keyVal = sftk_FindAttribute(key, CKA_VALUE); | 168 keyVal = sftk_FindAttribute(key, CKA_VALUE); |
159 keySize = (!keyVal) ? 0 : keyVal->attrib.ulValueLen; | 169 keySize = (!keyVal) ? 0 : keyVal->attrib.ulValueLen; |
160 blockSize = keySize + sizeof(TLSPRFContext); | 170 blockSize = keySize + sizeof(TLSPRFContext); |
161 prf_cx = (TLSPRFContext *)PORT_Alloc(blockSize); | 171 prf_cx = (TLSPRFContext *)PORT_Alloc(blockSize); |
162 if (!prf_cx) | 172 if (!prf_cx) |
163 goto done; | 173 goto done; |
164 prf_cx->cxSize = blockSize; | 174 prf_cx->cxSize = blockSize; |
165 prf_cx->cxKeyLen = keySize; | 175 prf_cx->cxKeyLen = keySize; |
166 prf_cx->cxDataLen = 0; | 176 prf_cx->cxDataLen = 0; |
167 prf_cx->cxBufSize = blockSize - SFTK_OFFSETOF(TLSPRFContext, cxBuf); | 177 prf_cx->cxBufSize = blockSize - SFTK_OFFSETOF(TLSPRFContext, cxBuf); |
168 prf_cx->cxRv = SECSuccess; | 178 prf_cx->cxRv = SECSuccess; |
169 prf_cx->cxIsFIPS = (key->slot->slotID == FIPS_SLOT_ID); | 179 prf_cx->cxIsFIPS = (key->slot->slotID == FIPS_SLOT_ID); |
170 prf_cx->cxBufPtr = prf_cx->cxBuf; | 180 prf_cx->cxBufPtr = prf_cx->cxBuf; |
171 prf_cx->cxHashAlg = hash_alg; | 181 prf_cx->cxHashAlg = hash_alg; |
| 182 prf_cx->cxOutLen = out_len; |
172 if (keySize) | 183 if (keySize) |
173 PORT_Memcpy(prf_cx->cxBufPtr, keyVal->attrib.pValue, keySize); | 184 PORT_Memcpy(prf_cx->cxBufPtr, keyVal->attrib.pValue, keySize); |
174 | 185 |
175 context->hashInfo = (void *) prf_cx; | 186 context->hashInfo = (void *) prf_cx; |
176 context->cipherInfo = (void *) prf_cx; | 187 context->cipherInfo = (void *) prf_cx; |
177 context->hashUpdate = (SFTKHash) sftk_TLSPRFHashUpdate; | 188 context->hashUpdate = (SFTKHash) sftk_TLSPRFHashUpdate; |
178 context->end = (SFTKEnd) sftk_TLSPRFEnd; | 189 context->end = (SFTKEnd) sftk_TLSPRFEnd; |
179 context->update = (SFTKCipher) sftk_TLSPRFUpdate; | 190 context->update = (SFTKCipher) sftk_TLSPRFUpdate; |
180 context->verify = (SFTKVerify) sftk_TLSPRFVerify; | 191 context->verify = (SFTKVerify) sftk_TLSPRFVerify; |
181 context->destroy = (SFTKDestroy) sftk_TLSPRFNull; | 192 context->destroy = (SFTKDestroy) sftk_TLSPRFNull; |
182 context->hashdestroy = (SFTKDestroy) sftk_TLSPRFHashDestroy; | 193 context->hashdestroy = (SFTKDestroy) sftk_TLSPRFHashDestroy; |
183 crv = CKR_OK; | 194 crv = CKR_OK; |
184 | 195 |
185 done: | 196 done: |
186 if (keyVal) | 197 if (keyVal) |
187 sftk_FreeAttribute(keyVal); | 198 sftk_FreeAttribute(keyVal); |
188 return crv; | 199 return crv; |
189 } | 200 } |
190 | 201 |
OLD | NEW |