Bug Summary

File:root/firefox-clang/security/nss/lib/softoken/lowkey.c
Warning:line 476, column 21
Value stored to 'rv' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name lowkey.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/security/nss/lib/softoken/softoken_softokn -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/security/nss/lib/softoken/softoken_softokn -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG -D SHLIB_SUFFIX="so" -D SHLIB_PREFIX="lib" -D SOFTOKEN_LIB_NAME="libsoftokn3.so" -D SHLIB_VERSION="3" -D NSS_FIPS_DISABLED -D NSS_NO_INIT_SUPPORT -D NSS_X86_OR_X64 -D NSS_X64 -D NSS_USE_64 -D USE_UTIL_DIRECTLY -D NO_NSPR_10_SUPPORT -D SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES -D LINUX2_1 -D LINUX -D linux -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D HAVE_STRERROR -D XP_UNIX -D _REENTRANT -D NSS_DISABLE_DBM -D NSS_DISABLE_LIBPKIX -D NSS_USE_PKCS5_PBKD2_PARAMS2_ONLY -D SOFTOKEN_USE_PKCS5_PBKD2_PARAMS2_ONLY -I /root/firefox-clang/security/nss/lib/softoken -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/security/nss/lib/softoken/softoken_softokn -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/private/nss -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -D MOZILLA_CLIENT -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=tautological-type-limit-compare -Wno-range-loop-analysis -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-unknown-warning-option -Wno-character-conversion -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-09-01-224014-2642839-1 -x c /root/firefox-clang/security/nss/lib/softoken/lowkey.c
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4#include "lowkeyi.h"
5#include "secoid.h"
6#include "secitem.h"
7#include "secder.h"
8#include "base64.h"
9#include "secasn1.h"
10#include "secerr.h"
11#include "softoken.h"
12#include "ec.h"
13#include "kem.h"
14
15SEC_ASN1_MKSUB(SEC_AnyTemplate)
16SEC_ASN1_MKSUB(SEC_BitStringTemplate)
17SEC_ASN1_MKSUB(SEC_ObjectIDTemplate)
18SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
19SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
20
21const SEC_ASN1Template nsslowkey_AttributeTemplate[] = {
22 { SEC_ASN1_SEQUENCE0x10,
23 0, NULL((void*)0), sizeof(NSSLOWKEYAttribute) },
24 { SEC_ASN1_OBJECT_ID0x06, offsetof(NSSLOWKEYAttribute, attrType)__builtin_offsetof(NSSLOWKEYAttribute, attrType) },
25 { SEC_ASN1_SET_OF(0x02000 | 0x11) | SEC_ASN1_XTRN0,
26 offsetof(NSSLOWKEYAttribute, attrValue)__builtin_offsetof(NSSLOWKEYAttribute, attrValue),
27 SEC_ASN1_SUB(SEC_AnyTemplate)SEC_AnyTemplate_Util },
28 { 0 }
29};
30
31const SEC_ASN1Template nsslowkey_SetOfAttributeTemplate[] = {
32 { SEC_ASN1_SET_OF(0x02000 | 0x11), 0, nsslowkey_AttributeTemplate },
33};
34/* ASN1 Templates for new decoder/encoder */
35const SEC_ASN1Template nsslowkey_PrivateKeyInfoTemplate[] = {
36 { SEC_ASN1_SEQUENCE0x10,
37 0, NULL((void*)0), sizeof(NSSLOWKEYPrivateKeyInfo) },
38 { SEC_ASN1_INTEGER0x02,
39 offsetof(NSSLOWKEYPrivateKeyInfo, version)__builtin_offsetof(NSSLOWKEYPrivateKeyInfo, version) },
40 { SEC_ASN1_INLINE0x00800 | SEC_ASN1_XTRN0,
41 offsetof(NSSLOWKEYPrivateKeyInfo, algorithm)__builtin_offsetof(NSSLOWKEYPrivateKeyInfo, algorithm),
42 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate)SECOID_AlgorithmIDTemplate_Util },
43 { SEC_ASN1_OCTET_STRING0x04,
44 offsetof(NSSLOWKEYPrivateKeyInfo, privateKey)__builtin_offsetof(NSSLOWKEYPrivateKeyInfo, privateKey) },
45 { SEC_ASN1_OPTIONAL0x00100 | SEC_ASN1_CONSTRUCTED0x20 | SEC_ASN1_CONTEXT_SPECIFIC0x80 | 0,
46 offsetof(NSSLOWKEYPrivateKeyInfo, attributes)__builtin_offsetof(NSSLOWKEYPrivateKeyInfo, attributes),
47 nsslowkey_SetOfAttributeTemplate },
48 { 0 }
49};
50
51const SEC_ASN1Template nsslowkey_SubjectPublicKeyInfoTemplate[] = {
52 { SEC_ASN1_SEQUENCE0x10, 0, NULL((void*)0), sizeof(NSSLOWKEYSubjectPublicKeyInfo) },
53 { SEC_ASN1_INLINE0x00800 | SEC_ASN1_XTRN0,
54 offsetof(NSSLOWKEYSubjectPublicKeyInfo, algorithm)__builtin_offsetof(NSSLOWKEYSubjectPublicKeyInfo, algorithm),
55 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate)SECOID_AlgorithmIDTemplate_Util },
56 { SEC_ASN1_BIT_STRING0x03,
57 offsetof(NSSLOWKEYSubjectPublicKeyInfo, subjectPublicKey)__builtin_offsetof(NSSLOWKEYSubjectPublicKeyInfo, subjectPublicKey
)
},
58 { 0 }
59};
60
61const SEC_ASN1Template nsslowkey_RSAPublicKeyTemplate[] = {
62 { SEC_ASN1_SEQUENCE0x10, 0, NULL((void*)0), sizeof(NSSLOWKEYPublicKey) },
63 { SEC_ASN1_INTEGER0x02, offsetof(NSSLOWKEYPublicKey, u.rsa.modulus)__builtin_offsetof(NSSLOWKEYPublicKey, u.rsa.modulus) },
64 { SEC_ASN1_INTEGER0x02, offsetof(NSSLOWKEYPublicKey, u.rsa.publicExponent)__builtin_offsetof(NSSLOWKEYPublicKey, u.rsa.publicExponent) },
65 { 0 }
66};
67
68const SEC_ASN1Template nsslowkey_PQGParamsTemplate[] = {
69 { SEC_ASN1_SEQUENCE0x10, 0, NULL((void*)0), sizeof(PQGParams) },
70 { SEC_ASN1_INTEGER0x02, offsetof(PQGParams, prime)__builtin_offsetof(PQGParams, prime) },
71 { SEC_ASN1_INTEGER0x02, offsetof(PQGParams, subPrime)__builtin_offsetof(PQGParams, subPrime) },
72 { SEC_ASN1_INTEGER0x02, offsetof(PQGParams, base)__builtin_offsetof(PQGParams, base) },
73 { 0 }
74};
75
76const SEC_ASN1Template nsslowkey_RSAPrivateKeyTemplate[] = {
77 { SEC_ASN1_SEQUENCE0x10, 0, NULL((void*)0), sizeof(NSSLOWKEYPrivateKey) },
78 { SEC_ASN1_INTEGER0x02, offsetof(NSSLOWKEYPrivateKey, u.rsa.version)__builtin_offsetof(NSSLOWKEYPrivateKey, u.rsa.version) },
79 { SEC_ASN1_INTEGER0x02, offsetof(NSSLOWKEYPrivateKey, u.rsa.modulus)__builtin_offsetof(NSSLOWKEYPrivateKey, u.rsa.modulus) },
80 { SEC_ASN1_INTEGER0x02, offsetof(NSSLOWKEYPrivateKey, u.rsa.publicExponent)__builtin_offsetof(NSSLOWKEYPrivateKey, u.rsa.publicExponent) },
81 { SEC_ASN1_INTEGER0x02, offsetof(NSSLOWKEYPrivateKey, u.rsa.privateExponent)__builtin_offsetof(NSSLOWKEYPrivateKey, u.rsa.privateExponent
)
},
82 { SEC_ASN1_INTEGER0x02, offsetof(NSSLOWKEYPrivateKey, u.rsa.prime1)__builtin_offsetof(NSSLOWKEYPrivateKey, u.rsa.prime1) },
83 { SEC_ASN1_INTEGER0x02, offsetof(NSSLOWKEYPrivateKey, u.rsa.prime2)__builtin_offsetof(NSSLOWKEYPrivateKey, u.rsa.prime2) },
84 { SEC_ASN1_INTEGER0x02, offsetof(NSSLOWKEYPrivateKey, u.rsa.exponent1)__builtin_offsetof(NSSLOWKEYPrivateKey, u.rsa.exponent1) },
85 { SEC_ASN1_INTEGER0x02, offsetof(NSSLOWKEYPrivateKey, u.rsa.exponent2)__builtin_offsetof(NSSLOWKEYPrivateKey, u.rsa.exponent2) },
86 { SEC_ASN1_INTEGER0x02, offsetof(NSSLOWKEYPrivateKey, u.rsa.coefficient)__builtin_offsetof(NSSLOWKEYPrivateKey, u.rsa.coefficient) },
87 { 0 }
88};
89
90const SEC_ASN1Template nsslowkey_DSAPrivateKeyTemplate[] = {
91 { SEC_ASN1_SEQUENCE0x10, 0, NULL((void*)0), sizeof(NSSLOWKEYPrivateKey) },
92 { SEC_ASN1_INTEGER0x02, offsetof(NSSLOWKEYPrivateKey, u.dsa.publicValue)__builtin_offsetof(NSSLOWKEYPrivateKey, u.dsa.publicValue) },
93 { SEC_ASN1_INTEGER0x02, offsetof(NSSLOWKEYPrivateKey, u.dsa.privateValue)__builtin_offsetof(NSSLOWKEYPrivateKey, u.dsa.privateValue) },
94 { 0 }
95};
96
97const SEC_ASN1Template nsslowkey_PQBothSeedAndPrivateKeyTemplate[] = {
98 { SEC_ASN1_SEQUENCE0x10, 0, NULL((void*)0), sizeof(NSSLOWKEYPrivateKey) },
99 { SEC_ASN1_OCTET_STRING0x04, offsetof(NSSLOWKEYPrivateKey, u.genpq.seedItem)__builtin_offsetof(NSSLOWKEYPrivateKey, u.genpq.seedItem) },
100 { SEC_ASN1_OCTET_STRING0x04, offsetof(NSSLOWKEYPrivateKey, u.genpq.keyItem)__builtin_offsetof(NSSLOWKEYPrivateKey, u.genpq.keyItem) },
101 { 0 }
102};
103
104const SEC_ASN1Template nsslowkey_PQSeedTemplate[] = {
105 /* the explicit | 0 here is source code doumentation, tell
106 * clang warnings to let it ride */
107 { SEC_ASN1_CONTEXT_SPECIFIC0x80 | SEC_ASN1_XTRN0 | 0, // NOLINT(misc-redundant-expression)
108 offsetof(NSSLOWKEYPrivateKey, u.genpq.seedItem)__builtin_offsetof(NSSLOWKEYPrivateKey, u.genpq.seedItem),
109 SEC_ASN1_SUB(SEC_OctetStringTemplate)SEC_OctetStringTemplate_Util },
110 { 0 }
111};
112const SEC_ASN1Template nsslowkey_PQPrivateKeyTemplate[] = {
113 { SEC_ASN1_OCTET_STRING0x04, offsetof(NSSLOWKEYPrivateKey, u.genpq.keyItem)__builtin_offsetof(NSSLOWKEYPrivateKey, u.genpq.keyItem) },
114 { 0 }
115};
116
117const SEC_ASN1Template nsslowkey_DSAPrivateKeyExportTemplate[] = {
118 { SEC_ASN1_INTEGER0x02, offsetof(NSSLOWKEYPrivateKey, u.dsa.privateValue)__builtin_offsetof(NSSLOWKEYPrivateKey, u.dsa.privateValue) },
119};
120
121const SEC_ASN1Template nsslowkey_DHPrivateKeyTemplate[] = {
122 { SEC_ASN1_SEQUENCE0x10, 0, NULL((void*)0), sizeof(NSSLOWKEYPrivateKey) },
123 { SEC_ASN1_INTEGER0x02, offsetof(NSSLOWKEYPrivateKey, u.dh.publicValue)__builtin_offsetof(NSSLOWKEYPrivateKey, u.dh.publicValue) },
124 { SEC_ASN1_INTEGER0x02, offsetof(NSSLOWKEYPrivateKey, u.dh.privateValue)__builtin_offsetof(NSSLOWKEYPrivateKey, u.dh.privateValue) },
125 { SEC_ASN1_INTEGER0x02, offsetof(NSSLOWKEYPrivateKey, u.dh.base)__builtin_offsetof(NSSLOWKEYPrivateKey, u.dh.base) },
126 { SEC_ASN1_INTEGER0x02, offsetof(NSSLOWKEYPrivateKey, u.dh.prime)__builtin_offsetof(NSSLOWKEYPrivateKey, u.dh.prime) },
127 { 0 }
128};
129
130/* NOTE: The SECG specification allows the private key structure
131 * to contain curve parameters but recommends that they be stored
132 * in the PrivateKeyAlgorithmIdentifier field of the PrivateKeyInfo
133 * instead.
134 */
135const SEC_ASN1Template nsslowkey_ECPrivateKeyTemplate[] = {
136 { SEC_ASN1_SEQUENCE0x10, 0, NULL((void*)0), sizeof(NSSLOWKEYPrivateKey) },
137 { SEC_ASN1_INTEGER0x02, offsetof(NSSLOWKEYPrivateKey, u.ec.version)__builtin_offsetof(NSSLOWKEYPrivateKey, u.ec.version) },
138 { SEC_ASN1_OCTET_STRING0x04,
139 offsetof(NSSLOWKEYPrivateKey, u.ec.privateValue)__builtin_offsetof(NSSLOWKEYPrivateKey, u.ec.privateValue) },
140 /* We only support named curves for which the parameters are
141 * encoded as an object ID.
142 */
143 { SEC_ASN1_OPTIONAL0x00100 | SEC_ASN1_CONSTRUCTED0x20 |
144 SEC_ASN1_EXPLICIT0x00200 | SEC_ASN1_CONTEXT_SPECIFIC0x80 |
145 SEC_ASN1_XTRN0 | 0,
146 offsetof(NSSLOWKEYPrivateKey, u.ec.ecParams.curveOID)__builtin_offsetof(NSSLOWKEYPrivateKey, u.ec.ecParams.curveOID
)
,
147 SEC_ASN1_SUB(SEC_ObjectIDTemplate)SEC_ObjectIDTemplate_Util },
148 { SEC_ASN1_OPTIONAL0x00100 | SEC_ASN1_CONSTRUCTED0x20 |
149 SEC_ASN1_EXPLICIT0x00200 | SEC_ASN1_CONTEXT_SPECIFIC0x80 |
150 SEC_ASN1_XTRN0 | 1,
151 offsetof(NSSLOWKEYPrivateKey, u.ec.publicValue)__builtin_offsetof(NSSLOWKEYPrivateKey, u.ec.publicValue),
152 SEC_ASN1_SUB(SEC_BitStringTemplate)SEC_BitStringTemplate_Util },
153 { 0 }
154};
155/*
156 * See bugzilla bug 125359
157 * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
158 * all of the templates above that en/decode into integers must be converted
159 * from ASN.1's signed integer type. This is done by marking either the
160 * source or destination (encoding or decoding, respectively) type as
161 * siUnsignedInteger.
162 */
163
164void
165prepare_low_rsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
166{
167 key->u.rsa.modulus.type = siUnsignedInteger;
168 key->u.rsa.publicExponent.type = siUnsignedInteger;
169 key->u.rsa.privateExponent.type = siUnsignedInteger;
170 key->u.rsa.prime1.type = siUnsignedInteger;
171 key->u.rsa.prime2.type = siUnsignedInteger;
172 key->u.rsa.exponent1.type = siUnsignedInteger;
173 key->u.rsa.exponent2.type = siUnsignedInteger;
174 key->u.rsa.coefficient.type = siUnsignedInteger;
175}
176
177void
178prepare_low_rsa_pub_key_for_asn1(NSSLOWKEYPublicKey *key)
179{
180 key->u.rsa.modulus.type = siUnsignedInteger;
181 key->u.rsa.publicExponent.type = siUnsignedInteger;
182}
183
184void
185prepare_low_pqg_params_for_asn1(PQGParams *params)
186{
187 params->prime.type = siUnsignedInteger;
188 params->subPrime.type = siUnsignedInteger;
189 params->base.type = siUnsignedInteger;
190}
191
192void
193prepare_low_dsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
194{
195 key->u.dsa.publicValue.type = siUnsignedInteger;
196 key->u.dsa.privateValue.type = siUnsignedInteger;
197 key->u.dsa.params.prime.type = siUnsignedInteger;
198 key->u.dsa.params.subPrime.type = siUnsignedInteger;
199 key->u.dsa.params.base.type = siUnsignedInteger;
200}
201
202void
203prepare_low_dsa_priv_key_export_for_asn1(NSSLOWKEYPrivateKey *key)
204{
205 key->u.dsa.privateValue.type = siUnsignedInteger;
206}
207
208void
209prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
210{
211 key->u.dh.prime.type = siUnsignedInteger;
212 key->u.dh.base.type = siUnsignedInteger;
213 key->u.dh.publicValue.type = siUnsignedInteger;
214 key->u.dh.privateValue.type = siUnsignedInteger;
215}
216
217void
218prepare_low_ecparams_for_asn1(ECParams *params)
219{
220 params->DEREncoding.type = siUnsignedInteger;
221 params->curveOID.type = siUnsignedInteger;
222}
223
224void
225prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
226{
227 key->u.ec.version.type = siUnsignedInteger;
228 key->u.ec.ecParams.DEREncoding.type = siUnsignedInteger;
229 key->u.ec.ecParams.curveOID.type = siUnsignedInteger;
230 key->u.ec.privateValue.type = siUnsignedInteger;
231 key->u.ec.publicValue.type = siUnsignedInteger;
232}
233
234void
235nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *privk)
236{
237 if (privk && privk->arena) {
238 PORT_FreeArenaPORT_FreeArena_Util(privk->arena, PR_TRUE1);
239 }
240}
241
242void
243nsslowkey_DestroyPublicKey(NSSLOWKEYPublicKey *pubk)
244{
245 if (pubk && pubk->arena) {
246 PORT_FreeArenaPORT_FreeArena_Util(pubk->arena, PR_TRUE1);
247 }
248}
249unsigned
250nsslowkey_PublicModulusLen(NSSLOWKEYPublicKey *pubk)
251{
252 /* interpret modulus length as key strength... in
253 * fortezza that's the public key length */
254
255 switch (pubk->keyType) {
256 case NSSLOWKEYRSAKey:
257 if (pubk->u.rsa.modulus.len == 0) {
258 return 0;
259 }
260 if (pubk->u.rsa.modulus.data[0] == 0) {
261 return pubk->u.rsa.modulus.len - 1;
262 }
263 return pubk->u.rsa.modulus.len;
264 default:
265 break;
266 }
267 return 0;
268}
269
270unsigned
271nsslowkey_PrivateModulusLen(NSSLOWKEYPrivateKey *privk)
272{
273 switch (privk->keyType) {
274 case NSSLOWKEYRSAKey:
275 if (privk->u.rsa.modulus.len == 0) {
276 return 0;
277 }
278 if (privk->u.rsa.modulus.data[0] == 0) {
279 return privk->u.rsa.modulus.len - 1;
280 }
281 return privk->u.rsa.modulus.len;
282 default:
283 break;
284 }
285 return 0;
286}
287
288NSSLOWKEYPublicKey *
289nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk)
290{
291 NSSLOWKEYPublicKey *pubk;
292 SECItem publicValue;
293 PLArenaPool *arena;
294
295 arena = PORT_NewArenaPORT_NewArena_Util(DER_DEFAULT_CHUNKSIZE(2048));
296 if (arena == NULL((void*)0)) {
297 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_NO_MEMORY);
298 return NULL((void*)0);
299 }
300
301 switch (privk->keyType) {
302 case NSSLOWKEYRSAKey:
303 case NSSLOWKEYNullKey:
304 pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAllocPORT_ArenaZAlloc_Util(arena,
305 sizeof(NSSLOWKEYPublicKey));
306 if (pubk != NULL((void*)0)) {
307 SECStatus rv;
308
309 pubk->arena = arena;
310 pubk->keyType = privk->keyType;
311 if (privk->keyType == NSSLOWKEYNullKey)
312 return pubk;
313 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(arena, &pubk->u.rsa.modulus,
314 &privk->u.rsa.modulus);
315 if (rv == SECSuccess) {
316 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(arena, &pubk->u.rsa.publicExponent,
317 &privk->u.rsa.publicExponent);
318 if (rv == SECSuccess) {
319 /* this key was already verified fully as
320 * a private key */
321 pubk->u.rsa.needVerify = PR_FALSE0;
322 return pubk;
323 }
324 }
325 } else {
326 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_NO_MEMORY);
327 }
328 break;
329 case NSSLOWKEYDSAKey:
330 pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAllocPORT_ArenaZAlloc_Util(arena,
331 sizeof(NSSLOWKEYPublicKey));
332 if (pubk != NULL((void*)0)) {
333 SECStatus rv;
334
335 pubk->arena = arena;
336 pubk->keyType = privk->keyType;
337 /* if the public key value doesn't exist, calculate it */
338 if (privk->u.dsa.publicValue.len == 0) {
339 rv = DH_Derive(&privk->u.dsa.params.base, &privk->u.dsa.params.prime,
340 &privk->u.dsa.privateValue, &publicValue, 0);
341 if (rv != SECSuccess) {
342 break;
343 }
344 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(privk->arena, &privk->u.dsa.publicValue, &publicValue);
345 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&publicValue, PR_FALSE0);
346 if (rv != SECSuccess) {
347 break;
348 }
349 }
350 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(arena, &pubk->u.dsa.publicValue,
351 &privk->u.dsa.publicValue);
352 if (rv != SECSuccess)
353 break;
354 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(arena, &pubk->u.dsa.params.prime,
355 &privk->u.dsa.params.prime);
356 if (rv != SECSuccess)
357 break;
358 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(arena, &pubk->u.dsa.params.subPrime,
359 &privk->u.dsa.params.subPrime);
360 if (rv != SECSuccess)
361 break;
362 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(arena, &pubk->u.dsa.params.base,
363 &privk->u.dsa.params.base);
364 if (rv == SECSuccess)
365 return pubk;
366 }
367 break;
368 case NSSLOWKEYDHKey:
369 pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAllocPORT_ArenaZAlloc_Util(arena,
370 sizeof(NSSLOWKEYPublicKey));
371 if (pubk != NULL((void*)0)) {
372 SECStatus rv;
373
374 pubk->arena = arena;
375 pubk->keyType = privk->keyType;
376 /* if the public key value doesn't exist, calculate it */
377 if (privk->u.dh.publicValue.len == 0) {
378 rv = DH_Derive(&privk->u.dh.base, &privk->u.dh.prime,
379 &privk->u.dh.privateValue, &publicValue, 0);
380 if (rv != SECSuccess) {
381 break;
382 }
383 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(privk->arena, &privk->u.dh.publicValue, &publicValue);
384 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&publicValue, PR_FALSE0);
385 if (rv != SECSuccess) {
386 break;
387 }
388 }
389 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(arena, &pubk->u.dh.publicValue,
390 &privk->u.dh.publicValue);
391 if (rv != SECSuccess)
392 break;
393 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(arena, &pubk->u.dh.prime,
394 &privk->u.dh.prime);
395 if (rv != SECSuccess)
396 break;
397 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(arena, &pubk->u.dh.base,
398 &privk->u.dh.base);
399 if (rv == SECSuccess)
400 return pubk;
401 }
402 break;
403 case NSSLOWKEYECKey:
404 pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAllocPORT_ArenaZAlloc_Util(arena,
405 sizeof(NSSLOWKEYPublicKey));
406 if (pubk != NULL((void*)0)) {
407 SECStatus rv;
408
409 pubk->arena = arena;
410 pubk->keyType = privk->keyType;
411
412 /* if the public key value doesn't exist, calculate it */
413 if (privk->u.ec.publicValue.len == 0) {
414 /* Checking if it's an ed25519 or x25519 key.
415 If it's the case, we derive the public key using the private key. */
416 SECOidTag privKeyOIDTag = SECOID_FindOIDTagSECOID_FindOIDTag_Util(&privk->u.ec.ecParams.curveOID);
417 if (privKeyOIDTag == SEC_OID_ED25519_PUBLIC_KEY) {
418 PORT_Memsetmemset(&privk->u.ec.publicValue, 0, sizeof(privk->u.ec.publicValue));
419 if (SECITEM_AllocItemSECITEM_AllocItem_Util(privk->arena, &privk->u.ec.publicValue, Ed25519_PUBLIC_KEYLEN32) == NULL((void*)0)) {
420 break;
421 }
422
423 rv = ED_DerivePublicKey(&privk->u.ec.privateValue, &privk->u.ec.publicValue);
424 if (rv != CKR_OK0x00000000UL) {
425 break;
426 }
427 } else if (privKeyOIDTag == SEC_OID_X25519) {
428 PORT_Memsetmemset(&privk->u.ec.publicValue, 0, sizeof(privk->u.ec.publicValue));
429 if (SECITEM_AllocItemSECITEM_AllocItem_Util(privk->arena, &privk->u.ec.publicValue, X25519_PUBLIC_KEYLEN32) == NULL((void*)0)) {
430 break;
431 }
432
433 rv = X25519_DerivePublicKey(&privk->u.ec.privateValue, &privk->u.ec.publicValue);
434 if (rv != CKR_OK0x00000000UL) {
435 break;
436 }
437 }
438 }
439
440 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(arena, &pubk->u.ec.publicValue,
441 &privk->u.ec.publicValue);
442 if (rv != SECSuccess)
443 break;
444 pubk->u.ec.ecParams.arena = arena;
445 /* Copy the rest of the params */
446 rv = EC_CopyParams(arena, &(pubk->u.ec.ecParams),
447 &(privk->u.ec.ecParams));
448 if (rv == SECSuccess)
449 return pubk;
450 }
451 break;
452 case NSSLOWKEYMLDSAKey:
453 pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAllocPORT_ArenaZAlloc_Util(arena,
454 sizeof(NSSLOWKEYPublicKey));
455 if (pubk != NULL((void*)0)) {
456 SECStatus rv;
457 SECItem seed = { siBuffer, NULL((void*)0), 0 };
458 MLDSAPrivateKey newPrivKey;
459
460 pubk->arena = arena;
461 pubk->keyType = privk->keyType;
462
463 /* privatekey value is encoded (rho, K, tr, s1, s2, t0) */
464 /* publickey value is encoded (rho, t1) */
465 /* Future, we can calculate public key directly from
466 * privatekey value as follows :
467 * A^ = ExpandA(rho);
468 * t = NTT-1(A^ o NSS(s1)) + s2
469 * (t1, t0) = Power2Round(t)
470 * we now have rho and t1 so we can encode public key.
471 * these functions are all specified in FIPS-204. For now
472 * we just use the seed if it's a available and regenerate
473 * both keys, and discard the private key. */
474 if (privk->u.mldsa.seedLen == 0) {
475 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_PKCS11_FUNCTION_FAILED);
476 rv = SECFailure;
Value stored to 'rv' is never read
477 break;
478 }
479 seed.data = privk->u.mldsa.seed;
480 seed.len = privk->u.mldsa.seedLen;
481 rv = MLDSA_NewKey(privk->u.mldsa.paramSet, &seed,
482 &newPrivKey, &pubk->u.mldsa);
483 if (rv != SECSuccess) {
484 break;
485 }
486 PORT_SafeZero(&newPrivKey, sizeof(newPrivKey));
487 return pubk;
488 }
489 break;
490 case NSSLOWKEYMLKEMKey:
491 pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAllocPORT_ArenaZAlloc_Util(arena,
492 sizeof(NSSLOWKEYPublicKey));
493 if (pubk != NULL((void*)0)) {
494 size_t pubKeyLen;
495 SECItem *item = NULL((void*)0);
496
497 pubk->arena = arena;
498 pubk->keyType = privk->keyType;
499 pubk->u.mlkem.mlkemParams = privk->u.mlkem.mlkemParams;
500 /* privatekey value is encoded (dPKE||ePKE||H(ePKE)||z) */
501 /* publickey value is encoded (ePKE) */
502 /* size(dPKE) = 384k and size(ePKE)=384k+32,
503 * so size(dPKE) = size(ePKE)-32 */
504 pubKeyLen = sftk_kyber_pubKeyLen(pubk->u.mlkem.mlkemParams);
505 if (privk->u.mlkem.key.len < 2 * pubKeyLen) {
506 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_BAD_KEY);
507 break;
508 }
509 item = SECITEM_AllocItemSECITEM_AllocItem_Util(arena, &pubk->u.mlkem.key, (int)pubKeyLen);
510 if (item == NULL((void*)0)) {
511 break;
512 }
513 PORT_Memcpymemcpy(pubk->u.mlkem.key.data,
514 privk->u.mlkem.key.data + pubKeyLen - 32,
515 pubKeyLen);
516 return pubk;
517 }
518 break;
519 /* No Fortezza in Low Key implementations (Fortezza keys aren't
520 * stored in our data base */
521 default:
522 break;
523 }
524
525 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1);
526 return NULL((void*)0);
527}
528
529NSSLOWKEYPrivateKey *
530nsslowkey_CopyPrivateKey(NSSLOWKEYPrivateKey *privKey)
531{
532 NSSLOWKEYPrivateKey *returnKey = NULL((void*)0);
533 SECStatus rv = SECFailure;
534 PLArenaPool *poolp;
535
536 if (!privKey) {
537 return NULL((void*)0);
538 }
539
540 poolp = PORT_NewArenaPORT_NewArena_Util(DER_DEFAULT_CHUNKSIZE(2048));
541 if (!poolp) {
542 return NULL((void*)0);
543 }
544
545 returnKey = (NSSLOWKEYPrivateKey *)PORT_ArenaZAllocPORT_ArenaZAlloc_Util(poolp, sizeof(NSSLOWKEYPrivateKey));
546 if (!returnKey) {
547 rv = SECFailure;
548 goto loser;
549 }
550
551 returnKey->keyType = privKey->keyType;
552 returnKey->arena = poolp;
553
554 switch (privKey->keyType) {
555 case NSSLOWKEYRSAKey:
556 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(poolp, &(returnKey->u.rsa.modulus),
557 &(privKey->u.rsa.modulus));
558 if (rv != SECSuccess)
559 break;
560 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(poolp, &(returnKey->u.rsa.version),
561 &(privKey->u.rsa.version));
562 if (rv != SECSuccess)
563 break;
564 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(poolp, &(returnKey->u.rsa.publicExponent),
565 &(privKey->u.rsa.publicExponent));
566 if (rv != SECSuccess)
567 break;
568 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(poolp, &(returnKey->u.rsa.privateExponent),
569 &(privKey->u.rsa.privateExponent));
570 if (rv != SECSuccess)
571 break;
572 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(poolp, &(returnKey->u.rsa.prime1),
573 &(privKey->u.rsa.prime1));
574 if (rv != SECSuccess)
575 break;
576 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(poolp, &(returnKey->u.rsa.prime2),
577 &(privKey->u.rsa.prime2));
578 if (rv != SECSuccess)
579 break;
580 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(poolp, &(returnKey->u.rsa.exponent1),
581 &(privKey->u.rsa.exponent1));
582 if (rv != SECSuccess)
583 break;
584 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(poolp, &(returnKey->u.rsa.exponent2),
585 &(privKey->u.rsa.exponent2));
586 if (rv != SECSuccess)
587 break;
588 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(poolp, &(returnKey->u.rsa.coefficient),
589 &(privKey->u.rsa.coefficient));
590 if (rv != SECSuccess)
591 break;
592 break;
593 case NSSLOWKEYDSAKey:
594 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(poolp, &(returnKey->u.dsa.publicValue),
595 &(privKey->u.dsa.publicValue));
596 if (rv != SECSuccess)
597 break;
598 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(poolp, &(returnKey->u.dsa.privateValue),
599 &(privKey->u.dsa.privateValue));
600 if (rv != SECSuccess)
601 break;
602 returnKey->u.dsa.params.arena = poolp;
603 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(poolp, &(returnKey->u.dsa.params.prime),
604 &(privKey->u.dsa.params.prime));
605 if (rv != SECSuccess)
606 break;
607 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(poolp, &(returnKey->u.dsa.params.subPrime),
608 &(privKey->u.dsa.params.subPrime));
609 if (rv != SECSuccess)
610 break;
611 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(poolp, &(returnKey->u.dsa.params.base),
612 &(privKey->u.dsa.params.base));
613 if (rv != SECSuccess)
614 break;
615 break;
616 case NSSLOWKEYDHKey:
617 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(poolp, &(returnKey->u.dh.publicValue),
618 &(privKey->u.dh.publicValue));
619 if (rv != SECSuccess)
620 break;
621 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(poolp, &(returnKey->u.dh.privateValue),
622 &(privKey->u.dh.privateValue));
623 if (rv != SECSuccess)
624 break;
625 returnKey->u.dsa.params.arena = poolp;
626 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(poolp, &(returnKey->u.dh.prime),
627 &(privKey->u.dh.prime));
628 if (rv != SECSuccess)
629 break;
630 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(poolp, &(returnKey->u.dh.base),
631 &(privKey->u.dh.base));
632 if (rv != SECSuccess)
633 break;
634 break;
635 case NSSLOWKEYECKey:
636 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(poolp, &(returnKey->u.ec.version),
637 &(privKey->u.ec.version));
638 if (rv != SECSuccess)
639 break;
640 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(poolp, &(returnKey->u.ec.publicValue),
641 &(privKey->u.ec.publicValue));
642 if (rv != SECSuccess)
643 break;
644 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(poolp, &(returnKey->u.ec.privateValue),
645 &(privKey->u.ec.privateValue));
646 if (rv != SECSuccess)
647 break;
648 returnKey->u.ec.ecParams.arena = poolp;
649 /* Copy the rest of the params */
650 rv = EC_CopyParams(poolp, &(returnKey->u.ec.ecParams),
651 &(privKey->u.ec.ecParams));
652 if (rv != SECSuccess)
653 break;
654 break;
655 case NSSLOWKEYMLDSAKey:
656 returnKey->u.mldsa = privKey->u.mldsa;
657 rv = SECSuccess;
658 break;
659 case NSSLOWKEYMLKEMKey:
660 returnKey->u.mlkem.mlkemParams = privKey->u.mlkem.mlkemParams;
661 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(poolp, &(returnKey->u.mlkem.key),
662 &(privKey->u.mlkem.key));
663 if (rv != SECSuccess)
664 break;
665 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(poolp, &(returnKey->u.mlkem.seed),
666 &(privKey->u.mlkem.seed));
667 if (rv != SECSuccess)
668 break;
669 break;
670 default:
671 rv = SECFailure;
672 }
673
674loser:
675
676 if (rv != SECSuccess) {
677 PORT_FreeArenaPORT_FreeArena_Util(poolp, PR_TRUE1);
678 returnKey = NULL((void*)0);
679 }
680
681 return returnKey;
682}