Coverage Report

Created: 2025-07-12 06:17

/src/S2OPC/src/Common/crypto/sopc_crypto_provider.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Licensed to Systerel under one or more contributor license
3
 * agreements. See the NOTICE file distributed with this work
4
 * for additional information regarding copyright ownership.
5
 * Systerel licenses this file to you under the Apache
6
 * License, Version 2.0 (the "License"); you may not use this
7
 * file except in compliance with the License. You may obtain
8
 * a copy of the License at
9
 *
10
 *   http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing,
13
 * software distributed under the License is distributed on an
14
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
 * KIND, either express or implied.  See the License for the
16
 * specific language governing permissions and limitations
17
 * under the License.
18
 */
19
20
#include <string.h>
21
22
#include "sopc_crypto_provider.h"
23
24
#include "sopc_assert.h"
25
#include "sopc_crypto_profiles.h"
26
#include "sopc_crypto_provider_lib_itf.h"
27
#include "sopc_key_manager.h"
28
#include "sopc_macros.h"
29
#include "sopc_mem_alloc.h"
30
#include "sopc_pki_stack.h"
31
32
/* ------------------------------------------------------------------------------------------------
33
 * Local functions
34
 * ------------------------------------------------------------------------------------------------
35
 */
36
37
static inline SOPC_ReturnStatus fill_UInt32_FromPolicy(const SOPC_SecurityPolicy_Config* pPolicy,
38
                                                       uint32_t* pOut,
39
                                                       const uint32_t value)
40
0
{
41
0
    if (pPolicy->isInvalid)
42
0
    {
43
0
        return SOPC_STATUS_INVALID_PARAMETERS;
44
0
    }
45
0
    if (value == 0)
46
0
    {
47
0
        return SOPC_STATUS_NOK;
48
0
    }
49
0
    *pOut = value;
50
0
    return SOPC_STATUS_OK;
51
0
}
52
53
/** Returns the Client-Server policy
54
 * This function is safe and always return a non-NULL pointer
55
 * In case of invalid parameter the SOPC_SecurityPolicy_Invalid_ID configuration is returned
56
 */
57
static const SOPC_SecurityPolicy_Config* getCSSecurityPolicyFromProvider(const SOPC_CryptoProvider* pProvider)
58
0
{
59
0
    SOPC_SecurityPolicy_ID policy = SOPC_SecurityPolicy_Invalid_ID;
60
0
    if (NULL != pProvider)
61
0
    {
62
0
        const SOPC_CryptoProfile* pProfile = SOPC_CryptoProvider_GetProfileServices(pProvider);
63
0
        if (NULL != pProfile)
64
0
        {
65
0
            policy = pProfile->SecurityPolicyID;
66
0
        }
67
0
    }
68
0
    return SOPC_SecurityPolicy_Config_Get(policy);
69
0
}
70
71
/** Returns the PubSub policy
72
 * This function is safe and always return a non-NULL pointer
73
 * In case of invalid parameter the SOPC_SecurityPolicy_Invalid_ID configuration is returned
74
 */
75
static const SOPC_SecurityPolicy_Config* getPSSecurityPolicyFromProvider(const SOPC_CryptoProvider* pProvider)
76
0
{
77
0
    SOPC_SecurityPolicy_ID policy = SOPC_SecurityPolicy_Invalid_ID;
78
0
    if (NULL != pProvider)
79
0
    {
80
0
        const SOPC_CryptoProfile_PubSub* pProfile = SOPC_CryptoProvider_GetProfilePubSub(pProvider);
81
0
        if (NULL != pProfile)
82
0
        {
83
0
            policy = pProfile->SecurityPolicyID;
84
0
        }
85
0
    }
86
0
    return SOPC_SecurityPolicy_Config_Get(policy);
87
0
}
88
89
static inline bool checkKeyLengthRange(const SOPC_SecurityPolicy_Config* pPolicy,
90
                                       uint32_t lenKey,
91
                                       const char** errorReason,
92
                                       bool isPublic)
93
0
{
94
0
    static const char* invalidKeyMsg[2] = {"invalid private key size for given profile",
95
0
                                           "invalid public key size for given profile"};
96
0
    bool result = true;
97
    // When not used, both Max and Min are equal to 0
98
0
    if (pPolicy->asymLen_KeyMaxBits > pPolicy->asymLen_KeyMinBits)
99
0
    {
100
0
        if (lenKey < pPolicy->asymLen_KeyMinBits || lenKey > pPolicy->asymLen_KeyMaxBits)
101
0
        {
102
0
            *errorReason = invalidKeyMsg[isPublic ? 1 : 0];
103
0
            result = false;
104
0
        }
105
0
    }
106
0
    else
107
0
    {
108
0
        *errorReason = "invalid security policy in cryptographic provider";
109
0
        result = false;
110
0
    }
111
0
    return result;
112
0
}
113
114
/* ------------------------------------------------------------------------------------------------
115
 * CryptoProvider
116
 * ------------------------------------------------------------------------------------------------
117
 */
118
119
SOPC_CryptoProvider* SOPC_CryptoProvider_Create(const char* uri)
120
0
{
121
0
    const SOPC_SecurityPolicy_Config* pProfileCfg = SOPC_CryptoProfile_Get(uri);
122
0
    if (NULL == pProfileCfg)
123
0
    {
124
0
        return NULL;
125
0
    }
126
0
    const SOPC_CryptoProfile* pProfile = pProfileCfg->profile;
127
0
    if (NULL == pProfile)
128
0
    {
129
0
        return NULL;
130
0
    }
131
132
0
    SOPC_CryptoProvider* pCryptoProvider = SOPC_Calloc(1, sizeof(SOPC_CryptoProvider));
133
0
    if (NULL != pCryptoProvider)
134
0
    {
135
        // The crypto provider profile shall be const after this init
136
0
        SOPC_GCC_DIAGNOSTIC_IGNORE_CAST_CONST
137
0
        *(const SOPC_CryptoProfile**) (&pCryptoProvider->pProfile) = pProfile;
138
0
        SOPC_GCC_DIAGNOSTIC_RESTORE
139
0
        if (SOPC_STATUS_OK != SOPC_CryptoProvider_Init(pCryptoProvider))
140
0
        {
141
0
            SOPC_Free(pCryptoProvider);
142
0
            pCryptoProvider = NULL;
143
0
        }
144
0
    }
145
146
0
    return pCryptoProvider;
147
0
}
148
149
SOPC_CryptoProvider* SOPC_CryptoProvider_CreatePubSub(const char* uri)
150
0
{
151
0
    const SOPC_CryptoProfile_PubSub* pProfilePubSub = SOPC_CryptoProfile_PubSub_Get(uri);
152
0
    if (NULL == pProfilePubSub)
153
0
    {
154
0
        return NULL;
155
0
    }
156
157
0
    SOPC_CryptoProvider* pCryptoProvider = SOPC_Calloc(1, sizeof(SOPC_CryptoProvider));
158
0
    if (NULL != pCryptoProvider)
159
0
    {
160
        // The crypto provider profile shall be const after this init
161
0
        SOPC_GCC_DIAGNOSTIC_IGNORE_CAST_CONST
162
0
        *(const SOPC_CryptoProfile_PubSub**) (&pCryptoProvider->pProfilePubSub) = pProfilePubSub;
163
0
        SOPC_GCC_DIAGNOSTIC_RESTORE
164
0
        if (SOPC_STATUS_OK != SOPC_CryptoProvider_Init(pCryptoProvider))
165
0
        {
166
0
            SOPC_Free(pCryptoProvider);
167
0
            pCryptoProvider = NULL;
168
0
        }
169
0
    }
170
171
0
    return pCryptoProvider;
172
0
}
173
174
void SOPC_CryptoProvider_Free(SOPC_CryptoProvider* pCryptoProvider)
175
0
{
176
0
    if (NULL != pCryptoProvider)
177
0
    {
178
0
        SOPC_CryptoProvider_Deinit(pCryptoProvider);
179
0
        SOPC_Free(pCryptoProvider);
180
0
    }
181
0
}
182
183
const SOPC_CryptoProfile* SOPC_CryptoProvider_GetProfileServices(const SOPC_CryptoProvider* pProvider)
184
0
{
185
0
    SOPC_ASSERT(NULL != pProvider);
186
0
    if (NULL != pProvider->pProfilePubSub)
187
0
    {
188
0
        return NULL;
189
0
    }
190
0
    return pProvider->pProfile;
191
0
}
192
193
const SOPC_CryptoProfile_PubSub* SOPC_CryptoProvider_GetProfilePubSub(const SOPC_CryptoProvider* pProvider)
194
0
{
195
0
    SOPC_ASSERT(NULL != pProvider);
196
0
    if (NULL != pProvider->pProfile)
197
0
    {
198
0
        return NULL;
199
0
    }
200
0
    return pProvider->pProfilePubSub;
201
0
}
202
203
/* ------------------------------------------------------------------------------------------------
204
 * CryptoProvider get-length operations
205
 * ------------------------------------------------------------------------------------------------
206
 */
207
208
SOPC_ReturnStatus SOPC_CryptoProvider_SymmetricGetLength_CryptoKey(const SOPC_CryptoProvider* pProvider,
209
                                                                   uint32_t* pLength)
210
0
{
211
0
    if (NULL == pProvider || NULL == pLength)
212
0
    {
213
0
        return SOPC_STATUS_INVALID_PARAMETERS;
214
0
    }
215
216
0
    const SOPC_CryptoProfile* pProfile = SOPC_CryptoProvider_GetProfileServices(pProvider);
217
0
    const SOPC_CryptoProfile_PubSub* pProfilePubSub = SOPC_CryptoProvider_GetProfilePubSub(pProvider);
218
0
    SOPC_SecurityPolicy_ID uSecPolID = SOPC_SecurityPolicy_Invalid_ID;
219
0
    if (NULL != pProfile)
220
0
    {
221
0
        uSecPolID = pProfile->SecurityPolicyID;
222
0
    }
223
0
    else if (NULL != pProfilePubSub)
224
0
    {
225
0
        uSecPolID = pProfilePubSub->SecurityPolicyID;
226
0
    }
227
228
0
    uint32_t len = SOPC_SecurityPolicy_Config_Get(uSecPolID)->symmLen_CryptoKey;
229
230
0
    SOPC_ReturnStatus result = SOPC_STATUS_INVALID_PARAMETERS;
231
0
    if (len > 0)
232
0
    {
233
0
        *pLength = len;
234
0
        result = SOPC_STATUS_OK;
235
0
    }
236
0
    return result;
237
0
}
238
239
/* return a Client/Server or Pubsub policy */
240
static SOPC_SecurityPolicy_ID getAnySecurityPolicyFromProvider(const SOPC_CryptoProvider* pProvider)
241
0
{
242
0
    const SOPC_CryptoProfile* pProfile = SOPC_CryptoProvider_GetProfileServices(pProvider);
243
0
    const SOPC_CryptoProfile_PubSub* pProfilePubSub = SOPC_CryptoProvider_GetProfilePubSub(pProvider);
244
245
0
    SOPC_SecurityPolicy_ID uSecPolID = SOPC_SecurityPolicy_Invalid_ID;
246
0
    if (NULL != pProfile)
247
0
    {
248
0
        uSecPolID = pProfile->SecurityPolicyID;
249
0
    }
250
0
    else if (NULL != pProfilePubSub)
251
0
    {
252
0
        uSecPolID = pProfilePubSub->SecurityPolicyID;
253
0
    }
254
0
    return uSecPolID;
255
0
}
256
257
SOPC_ReturnStatus SOPC_CryptoProvider_SymmetricGetLength_Encryption(const SOPC_CryptoProvider* pProvider,
258
                                                                    uint32_t lengthIn,
259
                                                                    uint32_t* pLengthOut)
260
0
{
261
0
    if (NULL == pProvider || NULL == pLengthOut)
262
0
    {
263
0
        return SOPC_STATUS_INVALID_PARAMETERS;
264
0
    }
265
266
0
    SOPC_ReturnStatus result = SOPC_STATUS_INVALID_PARAMETERS;
267
0
    const SOPC_SecurityPolicy_ID uSecPolID = getAnySecurityPolicyFromProvider(pProvider);
268
269
0
    if (SOPC_SecurityPolicy_Config_Get(uSecPolID)->symmLen_CryptoKey > 0)
270
0
    {
271
0
        result = SOPC_STATUS_OK;
272
0
        *pLengthOut = lengthIn;
273
0
    }
274
275
0
    return result;
276
0
}
277
278
SOPC_ReturnStatus SOPC_CryptoProvider_SymmetricGetLength_Decryption(const SOPC_CryptoProvider* pProvider,
279
                                                                    uint32_t lengthIn,
280
                                                                    uint32_t* pLengthOut)
281
0
{
282
0
    if (NULL == pProvider || NULL == pLengthOut)
283
0
    {
284
0
        return SOPC_STATUS_INVALID_PARAMETERS;
285
0
    }
286
287
0
    SOPC_ReturnStatus result = SOPC_STATUS_INVALID_PARAMETERS;
288
0
    const SOPC_SecurityPolicy_ID uSecPolID = getAnySecurityPolicyFromProvider(pProvider);
289
290
0
    if (SOPC_SecurityPolicy_Config_Get(uSecPolID)->symmLen_CryptoKey > 0)
291
0
    {
292
0
        result = SOPC_STATUS_OK;
293
0
        *pLengthOut = lengthIn;
294
0
    }
295
296
0
    return result;
297
0
}
298
299
SOPC_ReturnStatus SOPC_CryptoProvider_SymmetricGetLength_SignKey(const SOPC_CryptoProvider* pProvider,
300
                                                                 uint32_t* pLength)
301
0
{
302
0
    if (NULL == pProvider || NULL == pLength)
303
0
    {
304
0
        return SOPC_STATUS_INVALID_PARAMETERS;
305
0
    }
306
307
0
    SOPC_ReturnStatus result = SOPC_STATUS_INVALID_PARAMETERS;
308
0
    const SOPC_SecurityPolicy_ID uSecPolID = getAnySecurityPolicyFromProvider(pProvider);
309
310
0
    const uint32_t signLen = SOPC_SecurityPolicy_Config_Get(uSecPolID)->symmLen_SignKey;
311
0
    if (signLen > 0)
312
0
    {
313
0
        result = SOPC_STATUS_OK;
314
0
        *pLength = signLen;
315
0
    }
316
317
0
    return result;
318
0
}
319
320
SOPC_ReturnStatus SOPC_CryptoProvider_SymmetricGetLength_Signature(const SOPC_CryptoProvider* pProvider,
321
                                                                   uint32_t* pLength)
322
0
{
323
0
    if (NULL == pProvider || NULL == pLength)
324
0
    {
325
0
        return SOPC_STATUS_INVALID_PARAMETERS;
326
0
    }
327
328
0
    SOPC_ReturnStatus result = SOPC_STATUS_INVALID_PARAMETERS;
329
0
    const SOPC_SecurityPolicy_ID uSecPolID = getAnySecurityPolicyFromProvider(pProvider);
330
331
0
    const uint32_t signature = SOPC_SecurityPolicy_Config_Get(uSecPolID)->symmLen_Signature;
332
0
    if (signature > 0)
333
0
    {
334
0
        result = SOPC_STATUS_OK;
335
0
        *pLength = signature;
336
0
    }
337
338
0
    return result;
339
0
}
340
341
SOPC_ReturnStatus SOPC_CryptoProvider_SymmetricGetLength_Blocks(const SOPC_CryptoProvider* pProvider,
342
                                                                uint32_t* pCipherTextBlockSize,
343
                                                                uint32_t* pPlainTextBlockSize)
344
0
{
345
0
    SOPC_ReturnStatus result = SOPC_STATUS_INVALID_PARAMETERS;
346
0
    const SOPC_SecurityPolicy_Config* pPolicy = getCSSecurityPolicyFromProvider(pProvider);
347
348
0
    const uint32_t size = pPolicy->symmLen_Block;
349
350
0
    if (size > 0)
351
0
    {
352
0
        if (NULL != pCipherTextBlockSize)
353
0
        {
354
0
            *pCipherTextBlockSize = size;
355
0
        }
356
0
        if (NULL != pPlainTextBlockSize)
357
0
        {
358
0
            *pPlainTextBlockSize = size;
359
0
        }
360
0
        result = SOPC_STATUS_OK;
361
0
    }
362
363
0
    return result;
364
0
}
365
366
SOPC_ReturnStatus SOPC_CryptoProvider_SymmetricGetLength_SecureChannelNonce(const SOPC_CryptoProvider* pProvider,
367
                                                                            uint32_t* pLenNonce)
368
0
{
369
0
    SOPC_ReturnStatus result = SOPC_STATUS_INVALID_PARAMETERS;
370
0
    const SOPC_SecurityPolicy_Config* pPolicy = getCSSecurityPolicyFromProvider(pProvider);
371
372
0
    const uint32_t len = pPolicy->secureChannelNonceLength;
373
374
0
    if (len > 0)
375
0
    {
376
0
        *pLenNonce = len;
377
0
        result = SOPC_STATUS_OK;
378
0
    }
379
0
    return result;
380
0
}
381
382
SOPC_ReturnStatus SOPC_CryptoProvider_DeriveGetLengths(const SOPC_CryptoProvider* pProvider,
383
                                                       uint32_t* pSymmCryptoKeyLength,
384
                                                       uint32_t* pSymmSignKeyLength,
385
                                                       uint32_t* pSymmInitVectorLength)
386
0
{
387
0
    SOPC_ReturnStatus status = SOPC_STATUS_NOK;
388
389
0
    if (NULL == pProvider || NULL == pSymmCryptoKeyLength || NULL == pSymmSignKeyLength ||
390
0
        NULL == pSymmInitVectorLength)
391
0
    {
392
0
        return SOPC_STATUS_INVALID_PARAMETERS;
393
0
    }
394
395
0
    *pSymmCryptoKeyLength = 0;
396
0
    *pSymmSignKeyLength = 0;
397
0
    *pSymmInitVectorLength = 0;
398
399
0
    status = SOPC_CryptoProvider_SymmetricGetLength_CryptoKey(pProvider, pSymmCryptoKeyLength);
400
0
    if (SOPC_STATUS_OK == status)
401
0
    {
402
0
        status = SOPC_CryptoProvider_SymmetricGetLength_SignKey(pProvider, pSymmSignKeyLength);
403
0
        if (SOPC_STATUS_OK == status)
404
0
        {
405
0
            status = SOPC_CryptoProvider_SymmetricGetLength_Blocks(pProvider, pSymmInitVectorLength, NULL);
406
0
        }
407
0
    }
408
409
0
    return status;
410
0
}
411
412
SOPC_ReturnStatus SOPC_CryptoProvider_AsymmetricGetLength_KeyBytes(const SOPC_CryptoProvider* pProvider,
413
                                                                   const SOPC_AsymmetricKey* pKey,
414
                                                                   uint32_t* pLenKeyBits)
415
0
{
416
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
417
418
0
    status = SOPC_CryptoProvider_AsymmetricGetLength_KeyBits(pProvider, pKey, pLenKeyBits);
419
0
    if (SOPC_STATUS_OK == status)
420
0
        *pLenKeyBits /= 8;
421
422
0
    return status;
423
0
}
424
425
SOPC_ReturnStatus SOPC_CryptoProvider_AsymmetricGetLength_OAEPHashLength(const SOPC_CryptoProvider* pProvider,
426
                                                                         uint32_t* pLength)
427
0
{
428
0
    if (NULL == pProvider || NULL == pLength)
429
0
    {
430
0
        return SOPC_STATUS_INVALID_PARAMETERS;
431
0
    }
432
433
0
    const SOPC_SecurityPolicy_Config* pPolicy = getCSSecurityPolicyFromProvider(pProvider);
434
0
    return fill_UInt32_FromPolicy(pPolicy, pLength, pPolicy->asymLen_OAEP_Hash);
435
0
}
436
437
SOPC_ReturnStatus SOPC_CryptoProvider_AsymmetricGetLength_Msgs(const SOPC_CryptoProvider* pProvider,
438
                                                               const SOPC_AsymmetricKey* pKey,
439
                                                               uint32_t* pCipherTextBlockSize,
440
                                                               uint32_t* pPlainTextBlockSize)
441
0
{
442
0
    SOPC_ReturnStatus statusA = SOPC_STATUS_OK, statusB = SOPC_STATUS_OK;
443
444
0
    if (NULL == pProvider || NULL == pKey)
445
0
        return SOPC_STATUS_INVALID_PARAMETERS;
446
447
0
    if (NULL != pCipherTextBlockSize)
448
0
    {
449
0
        *pCipherTextBlockSize = 0;
450
0
        statusA = SOPC_CryptoProvider_AsymmetricGetLength_MsgCipherText(pProvider, pKey, pCipherTextBlockSize);
451
0
    }
452
0
    if (NULL != pPlainTextBlockSize)
453
0
    {
454
0
        *pPlainTextBlockSize = 0;
455
0
        statusB = SOPC_CryptoProvider_AsymmetricGetLength_MsgPlainText(pProvider, pKey, pPlainTextBlockSize);
456
0
    }
457
458
0
    if (SOPC_STATUS_OK != statusA || SOPC_STATUS_OK != statusB)
459
0
        return SOPC_STATUS_NOK;
460
461
0
    return SOPC_STATUS_OK;
462
0
}
463
464
SOPC_ReturnStatus SOPC_CryptoProvider_AsymmetricGetLength_Encryption(const SOPC_CryptoProvider* pProvider,
465
                                                                     const SOPC_AsymmetricKey* pKey,
466
                                                                     uint32_t lengthIn,
467
                                                                     uint32_t* pLengthOut)
468
0
{
469
0
    uint32_t lenCiph = 0, lenPlain = 0;
470
0
    uint32_t nMsgs = 0;
471
472
0
    if (NULL == pProvider || NULL == pKey || NULL == pLengthOut)
473
0
        return SOPC_STATUS_INVALID_PARAMETERS;
474
475
0
    if (0 == lengthIn)
476
0
    {
477
0
        *pLengthOut = 0;
478
0
        return SOPC_STATUS_OK;
479
0
    }
480
481
0
    if (SOPC_STATUS_OK != SOPC_CryptoProvider_AsymmetricGetLength_Msgs(pProvider, pKey, &lenCiph, &lenPlain))
482
0
        return SOPC_STATUS_NOK;
483
484
    // Calculates the number of messages
485
0
    nMsgs = lengthIn / lenPlain;
486
0
    if ((lengthIn % lenPlain) > 0)
487
0
        ++nMsgs;
488
489
    // Deduces the output length
490
0
    *pLengthOut = nMsgs * lenCiph;
491
492
0
    return SOPC_STATUS_OK;
493
0
}
494
495
SOPC_ReturnStatus SOPC_CryptoProvider_AsymmetricGetLength_Decryption(const SOPC_CryptoProvider* pProvider,
496
                                                                     const SOPC_AsymmetricKey* pKey,
497
                                                                     uint32_t lengthIn,
498
                                                                     uint32_t* pLengthOut)
499
0
{
500
0
    uint32_t lenCiph = 0, lenPlain = 0;
501
0
    uint32_t nMsgs = 0;
502
503
0
    if (NULL == pProvider || NULL == pKey || NULL == pLengthOut)
504
0
        return SOPC_STATUS_INVALID_PARAMETERS;
505
506
0
    if (0 == lengthIn)
507
0
    {
508
0
        *pLengthOut = 0;
509
0
        return SOPC_STATUS_OK;
510
0
    }
511
512
0
    if (SOPC_STATUS_OK != SOPC_CryptoProvider_AsymmetricGetLength_Msgs(pProvider, pKey, &lenCiph, &lenPlain))
513
0
        return SOPC_STATUS_NOK;
514
515
    // Calculates the number of messages
516
0
    nMsgs = lengthIn / lenCiph;
517
0
    if ((lengthIn % lenCiph) > 0)
518
0
        ++nMsgs;
519
520
    // Deduces the output length
521
0
    *pLengthOut = nMsgs * lenPlain;
522
523
0
    return SOPC_STATUS_OK;
524
0
}
525
526
SOPC_ReturnStatus SOPC_CryptoProvider_AsymmetricGetLength_Signature(const SOPC_CryptoProvider* pProvider,
527
                                                                    const SOPC_AsymmetricKey* pKey,
528
                                                                    uint32_t* pLength)
529
0
{
530
0
    if (NULL == pProvider || NULL == pKey || NULL == pLength)
531
0
        return SOPC_STATUS_INVALID_PARAMETERS;
532
533
    // The signature is a message long.
534
0
    return SOPC_CryptoProvider_AsymmetricGetLength_Msgs(pProvider, pKey, pLength, NULL);
535
0
}
536
537
const char* SOPC_CryptoProvider_AsymmetricGetUri_SignAlgorithm(const SOPC_CryptoProvider* pProvider)
538
0
{
539
0
    const SOPC_SecurityPolicy_Config* pPolicy = getCSSecurityPolicyFromProvider(pProvider);
540
541
0
    return pPolicy->URI_SignAlgo;
542
0
}
543
544
SOPC_ReturnStatus SOPC_CryptoProvider_CertificateGetLength_Thumbprint(const SOPC_CryptoProvider* pProvider,
545
                                                                      uint32_t* pLength)
546
0
{
547
0
    const SOPC_SecurityPolicy_Config* pPolicy = getCSSecurityPolicyFromProvider(pProvider);
548
0
    return fill_UInt32_FromPolicy(pPolicy, pLength, pPolicy->certLen_Thumbprint);
549
0
}
550
551
SOPC_ReturnStatus SOPC_CryptoProvider_PubSubGetLength_KeyNonce(const SOPC_CryptoProvider* pProvider, uint32_t* pLength)
552
0
{
553
0
    if (NULL == pProvider || NULL == pLength)
554
0
    {
555
0
        return SOPC_STATUS_INVALID_PARAMETERS;
556
0
    }
557
558
0
    SOPC_ReturnStatus result = SOPC_STATUS_INVALID_PARAMETERS;
559
0
    const SOPC_SecurityPolicy_Config* pPolicy = getPSSecurityPolicyFromProvider(pProvider);
560
561
0
    const uint32_t len = pPolicy->symmLen_KeyNonce;
562
563
0
    if (len > 0)
564
0
    {
565
0
        *pLength = len;
566
0
        result = SOPC_STATUS_OK;
567
0
    }
568
0
    return result;
569
0
}
570
571
SOPC_ReturnStatus SOPC_CryptoProvider_PubSubGetLength_MessageRandom(const SOPC_CryptoProvider* pProvider,
572
                                                                    uint32_t* pLength)
573
0
{
574
0
    if (NULL == pProvider || NULL == pLength)
575
0
    {
576
0
        return SOPC_STATUS_INVALID_PARAMETERS;
577
0
    }
578
579
0
    SOPC_ReturnStatus result = SOPC_STATUS_INVALID_PARAMETERS;
580
0
    const SOPC_SecurityPolicy_Config* pPolicy = getPSSecurityPolicyFromProvider(pProvider);
581
582
0
    const uint32_t len = pPolicy->symmLen_MessageRandom;
583
584
0
    if (len > 0)
585
0
    {
586
0
        *pLength = len;
587
0
        result = SOPC_STATUS_OK;
588
0
    }
589
0
    return result;
590
0
}
591
592
/* ------------------------------------------------------------------------------------------------
593
 * Symmetric cryptography
594
 * ------------------------------------------------------------------------------------------------
595
 */
596
SOPC_ReturnStatus SOPC_CryptoProvider_SymmetricEncrypt(const SOPC_CryptoProvider* pProvider,
597
                                                       const uint8_t* pInput,
598
                                                       uint32_t lenPlainText,
599
                                                       const SOPC_SecretBuffer* pKey,
600
                                                       const SOPC_SecretBuffer* pIV,
601
                                                       uint8_t* pOutput,
602
                                                       uint32_t lenOutput)
603
0
{
604
0
    const SOPC_ExposedBuffer* pExpKey = NULL;
605
0
    const SOPC_ExposedBuffer* pExpIV = NULL;
606
0
    uint32_t lenCiphered = 0;
607
608
0
    if (NULL == pProvider || NULL == pInput || NULL == pKey || NULL == pIV || NULL == pOutput)
609
0
    {
610
0
        return SOPC_STATUS_INVALID_PARAMETERS;
611
0
    }
612
613
0
    const SOPC_SecurityPolicy_Config* pPolicy = getCSSecurityPolicyFromProvider(pProvider);
614
0
    const SOPC_CryptoProfile* pProfile = pPolicy->profile;
615
0
    if (NULL == pProfile || NULL == pProfile->pFnSymmEncrypt)
616
0
    {
617
0
        return SOPC_STATUS_INVALID_PARAMETERS;
618
0
    }
619
620
0
    SOPC_ReturnStatus status = SOPC_CryptoProvider_SymmetricGetLength_Encryption(pProvider, lenPlainText, &lenCiphered);
621
0
    if (SOPC_STATUS_OK != status || lenCiphered != lenOutput)
622
0
    {
623
0
        return SOPC_STATUS_INVALID_PARAMETERS;
624
0
    }
625
626
0
    if (pPolicy->symmLen_Block > 0 && pPolicy->symmLen_CryptoKey > 0)
627
0
    {
628
0
        if ((lenPlainText % pPolicy->symmLen_Block) != 0) // Not block-aligned
629
0
        {
630
0
            return SOPC_STATUS_INVALID_PARAMETERS;
631
0
        }
632
0
        if (SOPC_SecretBuffer_GetLength(pKey) != pPolicy->symmLen_CryptoKey) // Wrong key size
633
0
        {
634
0
            return SOPC_STATUS_INVALID_PARAMETERS;
635
0
        }
636
0
        if (SOPC_SecretBuffer_GetLength(pIV) != pPolicy->symmLen_Block)
637
0
        { // Wrong IV size (should be block size)
638
0
            return SOPC_STATUS_INVALID_PARAMETERS;
639
0
        }
640
0
    }
641
642
0
    pExpKey = SOPC_SecretBuffer_Expose(pKey);
643
0
    pExpIV = SOPC_SecretBuffer_Expose(pIV);
644
645
0
    status = pProfile->pFnSymmEncrypt(pProvider, pInput, lenPlainText, pExpKey, pExpIV, pOutput, lenOutput);
646
647
0
    SOPC_SecretBuffer_Unexpose(pExpKey, pKey);
648
0
    SOPC_SecretBuffer_Unexpose(pExpIV, pIV);
649
650
0
    return status;
651
0
}
652
653
SOPC_ReturnStatus SOPC_CryptoProvider_SymmetricDecrypt(const SOPC_CryptoProvider* pProvider,
654
                                                       const uint8_t* pInput,
655
                                                       uint32_t lenCipherText,
656
                                                       const SOPC_SecretBuffer* pKey,
657
                                                       const SOPC_SecretBuffer* pIV,
658
                                                       uint8_t* pOutput,
659
                                                       uint32_t lenOutput)
660
0
{
661
0
    const SOPC_ExposedBuffer* pExpKey = NULL;
662
0
    const SOPC_ExposedBuffer* pExpIV = NULL;
663
0
    uint32_t lenDeciphered = 0;
664
665
0
    if (NULL == pProvider || NULL == pInput || NULL == pKey || NULL == pIV || NULL == pOutput)
666
0
    {
667
0
        return SOPC_STATUS_INVALID_PARAMETERS;
668
0
    }
669
670
0
    const SOPC_SecurityPolicy_Config* pPolicy = getCSSecurityPolicyFromProvider(pProvider);
671
0
    const SOPC_CryptoProfile* pProfile = pPolicy->profile;
672
0
    if (NULL == pProfile || NULL == pProfile->pFnSymmDecrypt)
673
0
    {
674
0
        return SOPC_STATUS_INVALID_PARAMETERS;
675
0
    }
676
677
0
    SOPC_ReturnStatus status =
678
0
        SOPC_CryptoProvider_SymmetricGetLength_Decryption(pProvider, lenCipherText, &lenDeciphered);
679
0
    if (SOPC_STATUS_OK != status || lenDeciphered != lenOutput)
680
0
    {
681
0
        return SOPC_STATUS_INVALID_PARAMETERS;
682
0
    }
683
684
0
    if (pPolicy->symmLen_Block > 0 && pPolicy->symmLen_CryptoKey > 0)
685
0
    {
686
0
        if ((lenCipherText % pPolicy->symmLen_Block) != 0) // Not block-aligned
687
0
        {
688
0
            return SOPC_STATUS_INVALID_PARAMETERS;
689
0
        }
690
0
        if (SOPC_SecretBuffer_GetLength(pKey) != pPolicy->symmLen_CryptoKey) // Wrong key size
691
0
        {
692
0
            return SOPC_STATUS_INVALID_PARAMETERS;
693
0
        }
694
0
        if (SOPC_SecretBuffer_GetLength(pIV) != pPolicy->symmLen_Block)
695
0
        { // Wrong IV size (should be block size)
696
0
            return SOPC_STATUS_INVALID_PARAMETERS;
697
0
        }
698
0
    }
699
700
0
    pExpKey = SOPC_SecretBuffer_Expose(pKey);
701
0
    pExpIV = SOPC_SecretBuffer_Expose(pIV);
702
703
0
    status = pProfile->pFnSymmDecrypt(pProvider, pInput, lenCipherText, pExpKey, pExpIV, pOutput, lenOutput);
704
705
0
    SOPC_SecretBuffer_Unexpose(pExpKey, pKey);
706
0
    SOPC_SecretBuffer_Unexpose(pExpIV, pIV);
707
708
0
    return status;
709
0
}
710
711
SOPC_ReturnStatus SOPC_CryptoProvider_PubSubCrypt(const SOPC_CryptoProvider* pProvider,
712
                                                  const uint8_t* pInput,
713
                                                  uint32_t lenInput,
714
                                                  const SOPC_SecretBuffer* pKey,
715
                                                  const SOPC_SecretBuffer* pKeyNonce,
716
                                                  const SOPC_ExposedBuffer* pRandom,
717
                                                  uint32_t lenRandom,
718
                                                  uint32_t uSequenceNumber,
719
                                                  uint8_t* pOutput,
720
                                                  uint32_t lenOutput)
721
0
{
722
0
    if (NULL == pProvider || NULL == pInput || NULL == pKey || NULL == pKeyNonce || NULL == pRandom || NULL == pOutput)
723
0
    {
724
0
        return SOPC_STATUS_INVALID_PARAMETERS;
725
0
    }
726
0
    if (lenInput != lenOutput || 0 == lenInput)
727
0
    {
728
0
        return SOPC_STATUS_INVALID_PARAMETERS;
729
0
    }
730
731
0
    const SOPC_SecurityPolicy_Config* pPolicy = getPSSecurityPolicyFromProvider(pProvider);
732
0
    const SOPC_CryptoProfile_PubSub* pProfilePubSub = pPolicy->psProfile;
733
0
    if (NULL == pProfilePubSub || NULL == pProfilePubSub->pFnCrypt)
734
0
    {
735
0
        return SOPC_STATUS_INVALID_PARAMETERS;
736
0
    }
737
738
0
    SOPC_ReturnStatus status = SOPC_STATUS_INVALID_PARAMETERS;
739
740
0
    if (pPolicy->symmLen_CryptoKey > 0 && pPolicy->symmLen_KeyNonce > 0 && pPolicy->symmLen_MessageRandom > 0)
741
0
    {
742
0
        bool bInvalid;
743
        /* Key size check, KeyNonce size check, MessageRandom size check */
744
0
        bInvalid = (SOPC_SecretBuffer_GetLength(pKey) != pPolicy->symmLen_CryptoKey ||
745
0
                    SOPC_SecretBuffer_GetLength(pKeyNonce) != pPolicy->symmLen_KeyNonce ||
746
0
                    pPolicy->symmLen_MessageRandom != lenRandom);
747
0
        if (!bInvalid)
748
0
        {
749
0
            status = SOPC_STATUS_OK;
750
0
        }
751
0
    }
752
753
0
    if (SOPC_STATUS_OK == status)
754
0
    {
755
0
        const SOPC_ExposedBuffer* pExpKey = SOPC_SecretBuffer_Expose(pKey);
756
0
        const SOPC_ExposedBuffer* pExpNonce = SOPC_SecretBuffer_Expose(pKeyNonce);
757
758
0
        status = pProfilePubSub->pFnCrypt(pProvider, pInput, lenInput, pExpKey, pExpNonce, pRandom, uSequenceNumber,
759
0
                                          pOutput);
760
761
0
        SOPC_SecretBuffer_Unexpose(pExpKey, pKey);
762
0
        SOPC_SecretBuffer_Unexpose(pExpNonce, pKeyNonce);
763
0
    }
764
765
0
    return status;
766
0
}
767
768
SOPC_ReturnStatus SOPC_CryptoProvider_SymmetricSign(const SOPC_CryptoProvider* pProvider,
769
                                                    const uint8_t* pInput,
770
                                                    uint32_t lenInput,
771
                                                    const SOPC_SecretBuffer* pKey,
772
                                                    uint8_t* pOutput,
773
                                                    uint32_t lenOutput)
774
0
{
775
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
776
0
    const SOPC_ExposedBuffer* pExpKey = NULL;
777
0
    uint32_t len;
778
779
0
    if (NULL == pProvider || NULL == pInput || NULL == pKey || NULL == pOutput)
780
0
    {
781
0
        return SOPC_STATUS_INVALID_PARAMETERS;
782
0
    }
783
784
0
    const SOPC_CryptoProfile* pProfile = SOPC_CryptoProvider_GetProfileServices(pProvider);
785
0
    const SOPC_CryptoProfile_PubSub* pProfilePubSub = SOPC_CryptoProvider_GetProfilePubSub(pProvider);
786
0
    FnSymmetricSign* pFnSign = NULL;
787
0
    if (NULL != pProfile)
788
0
    {
789
0
        pFnSign = pProfile->pFnSymmSign;
790
0
    }
791
0
    else if (NULL != pProfilePubSub)
792
0
    {
793
0
        pFnSign = pProfilePubSub->pFnSymmSign;
794
0
    }
795
796
0
    if (NULL == pFnSign)
797
0
    {
798
0
        return SOPC_STATUS_INVALID_PARAMETERS;
799
0
    }
800
801
    // Assert output size
802
0
    if (SOPC_CryptoProvider_SymmetricGetLength_Signature(pProvider, &len) != SOPC_STATUS_OK)
803
0
    {
804
0
        return SOPC_STATUS_NOK;
805
0
    }
806
0
    if (lenOutput != len)
807
0
    {
808
0
        return SOPC_STATUS_INVALID_PARAMETERS;
809
0
    }
810
811
    // Assert key size
812
0
    if (SOPC_CryptoProvider_SymmetricGetLength_SignKey(pProvider, &len) != SOPC_STATUS_OK)
813
0
    {
814
0
        return SOPC_STATUS_NOK;
815
0
    }
816
0
    if (SOPC_SecretBuffer_GetLength(pKey) != len)
817
0
    {
818
0
        return SOPC_STATUS_INVALID_PARAMETERS;
819
0
    }
820
821
0
    pExpKey = SOPC_SecretBuffer_Expose(pKey);
822
0
    if (NULL == pExpKey)
823
0
    {
824
0
        return SOPC_STATUS_NOK;
825
0
    }
826
827
0
    status = pFnSign(pProvider, pInput, lenInput, pExpKey, pOutput);
828
829
0
    SOPC_SecretBuffer_Unexpose(pExpKey, pKey);
830
0
    return status;
831
0
}
832
833
SOPC_ReturnStatus SOPC_CryptoProvider_SymmetricVerify(const SOPC_CryptoProvider* pProvider,
834
                                                      const uint8_t* pInput,
835
                                                      uint32_t lenInput,
836
                                                      const SOPC_SecretBuffer* pKey,
837
                                                      const uint8_t* pSignature,
838
                                                      uint32_t lenOutput)
839
0
{
840
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
841
0
    const SOPC_ExposedBuffer* pExpKey = NULL;
842
0
    uint32_t len;
843
844
0
    if (NULL == pProvider || NULL == pInput || NULL == pKey || NULL == pSignature)
845
0
    {
846
0
        return SOPC_STATUS_INVALID_PARAMETERS;
847
0
    }
848
849
0
    const SOPC_CryptoProfile* pProfile = SOPC_CryptoProvider_GetProfileServices(pProvider);
850
0
    const SOPC_CryptoProfile_PubSub* pProfilePubSub = SOPC_CryptoProvider_GetProfilePubSub(pProvider);
851
0
    FnSymmetricVerify* pFnVerif = NULL;
852
0
    if (NULL != pProfile)
853
0
    {
854
0
        pFnVerif = pProfile->pFnSymmVerif;
855
0
    }
856
0
    else if (NULL != pProfilePubSub)
857
0
    {
858
0
        pFnVerif = pProfilePubSub->pFnSymmVerif;
859
0
    }
860
861
0
    if (NULL == pFnVerif)
862
0
    {
863
0
        return SOPC_STATUS_INVALID_PARAMETERS;
864
0
    }
865
866
    // Assert output size
867
0
    if (SOPC_CryptoProvider_SymmetricGetLength_Signature(pProvider, &len) != SOPC_STATUS_OK)
868
0
    {
869
0
        return SOPC_STATUS_NOK;
870
0
    }
871
0
    if (lenOutput != len)
872
0
    {
873
0
        return SOPC_STATUS_INVALID_PARAMETERS;
874
0
    }
875
876
    // Assert key size
877
0
    if (SOPC_CryptoProvider_SymmetricGetLength_SignKey(pProvider, &len) != SOPC_STATUS_OK)
878
0
    {
879
0
        return SOPC_STATUS_NOK;
880
0
    }
881
0
    if (SOPC_SecretBuffer_GetLength(pKey) != len)
882
0
    {
883
0
        return SOPC_STATUS_INVALID_PARAMETERS;
884
0
    }
885
886
0
    pExpKey = SOPC_SecretBuffer_Expose(pKey);
887
0
    if (NULL == pExpKey)
888
0
    {
889
0
        return SOPC_STATUS_NOK;
890
0
    }
891
892
0
    status = pFnVerif(pProvider, pInput, lenInput, pExpKey, pSignature);
893
894
0
    SOPC_SecretBuffer_Unexpose(pExpKey, pKey);
895
0
    return status;
896
0
}
897
898
/* ------------------------------------------------------------------------------------------------
899
 * Random and pseudo-random functionalities
900
 * ------------------------------------------------------------------------------------------------
901
 */
902
903
SOPC_ReturnStatus SOPC_CryptoProvider_GenerateRandomBytes(const SOPC_CryptoProvider* pProvider,
904
                                                          uint32_t nBytes,
905
                                                          SOPC_ExposedBuffer** ppBuffer)
906
0
{
907
0
    if (NULL == pProvider || nBytes == 0 || NULL == ppBuffer)
908
0
    {
909
0
        return SOPC_STATUS_INVALID_PARAMETERS;
910
0
    }
911
912
0
    const SOPC_CryptoProfile* pProfile = SOPC_CryptoProvider_GetProfileServices(pProvider);
913
0
    const SOPC_CryptoProfile_PubSub* pProfilePubSub = SOPC_CryptoProvider_GetProfilePubSub(pProvider);
914
0
    FnGenerateRandom* pFnRnd = NULL;
915
0
    if (NULL != pProfile)
916
0
    {
917
0
        pFnRnd = pProfile->pFnGenRnd;
918
0
    }
919
0
    else if (NULL != pProfilePubSub)
920
0
    {
921
0
        pFnRnd = pProfilePubSub->pFnGenRnd;
922
0
    }
923
924
0
    if (NULL == pFnRnd)
925
0
    {
926
0
        return SOPC_STATUS_INVALID_PARAMETERS;
927
0
    }
928
929
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
930
0
    SOPC_ExposedBuffer* pExp = NULL;
931
932
    /* Empties pointer in case an error occurs after that point. */
933
0
    *ppBuffer = NULL;
934
935
0
    pExp = SOPC_Malloc(nBytes);
936
0
    if (NULL == pExp)
937
0
    {
938
0
        status = SOPC_STATUS_NOK;
939
0
    }
940
941
0
    if (SOPC_STATUS_OK == status)
942
0
    {
943
0
        status = pFnRnd(pProvider, pExp, nBytes);
944
0
        if (SOPC_STATUS_OK == status)
945
0
        {
946
0
            *ppBuffer = pExp;
947
0
        }
948
0
        else
949
0
        {
950
0
            SOPC_Free(pExp);
951
0
        }
952
0
    }
953
954
0
    return status;
955
0
}
956
957
SOPC_ReturnStatus SOPC_CryptoProvider_GenerateSecureChannelNonce(const SOPC_CryptoProvider* pProvider,
958
                                                                 SOPC_SecretBuffer** ppNonce)
959
0
{
960
0
    uint32_t lenNonce = 0;
961
0
    SOPC_ExposedBuffer* pExp = NULL;
962
963
0
    if (NULL == pProvider || NULL == ppNonce)
964
0
    {
965
0
        return SOPC_STATUS_INVALID_PARAMETERS;
966
0
    }
967
968
0
    SOPC_ReturnStatus status = SOPC_CryptoProvider_SymmetricGetLength_SecureChannelNonce(pProvider, &lenNonce);
969
970
0
    if (SOPC_STATUS_OK == status)
971
0
    {
972
0
        status = SOPC_CryptoProvider_GenerateRandomBytes(pProvider, lenNonce, &pExp);
973
0
    }
974
975
0
    if (SOPC_STATUS_OK == status)
976
0
    {
977
0
        *ppNonce = SOPC_SecretBuffer_NewFromExposedBuffer(pExp, lenNonce);
978
0
        if (NULL == *ppNonce)
979
0
        {
980
0
            status = SOPC_STATUS_NOK;
981
0
        }
982
983
0
        memset(pExp, 0, lenNonce);
984
0
        SOPC_Free(pExp);
985
0
    }
986
987
0
    return status;
988
0
}
989
990
SOPC_ReturnStatus SOPC_CryptoProvider_GenerateRandomID(const SOPC_CryptoProvider* pProvider, uint32_t* pID)
991
0
{
992
0
    if (NULL == pProvider || NULL == pID)
993
0
    {
994
0
        return SOPC_STATUS_INVALID_PARAMETERS;
995
0
    }
996
997
0
    const SOPC_CryptoProfile* pProfile = SOPC_CryptoProvider_GetProfileServices(pProvider);
998
0
    if (NULL == pProfile || NULL == pProfile->pFnGenRnd)
999
0
    {
1000
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1001
0
    }
1002
1003
0
    return pProfile->pFnGenRnd(pProvider, (SOPC_ExposedBuffer*) pID, sizeof(uint32_t));
1004
0
}
1005
1006
SOPC_ReturnStatus SOPC_CryptoProvider_DerivePseudoRandomData(const SOPC_CryptoProvider* pProvider,
1007
                                                             const SOPC_ExposedBuffer* pSecret,
1008
                                                             uint32_t lenSecret,
1009
                                                             const SOPC_ExposedBuffer* pSeed,
1010
                                                             uint32_t lenSeed,
1011
                                                             SOPC_ExposedBuffer* pOutput,
1012
                                                             uint32_t lenOutput)
1013
0
{
1014
0
    if (NULL == pProvider || NULL == pProvider->pCryptolibContext || NULL == pSecret || 0 == lenSecret ||
1015
0
        NULL == pSeed || 0 == lenSeed || NULL == pOutput || 0 == lenOutput)
1016
0
    {
1017
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1018
0
    }
1019
1020
0
    const SOPC_CryptoProfile* pProfile = SOPC_CryptoProvider_GetProfileServices(pProvider);
1021
0
    if (NULL == pProfile || NULL == pProfile->pFnDeriveData)
1022
0
    {
1023
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1024
0
    }
1025
1026
0
    return pProfile->pFnDeriveData(pProvider, pSecret, lenSecret, pSeed, lenSeed, pOutput, lenOutput);
1027
0
}
1028
1029
static inline SOPC_ReturnStatus DeriveKS(const SOPC_CryptoProvider* pProvider,
1030
                                         const SOPC_ExposedBuffer* pSecret,
1031
                                         uint32_t lenSecret,
1032
                                         const SOPC_ExposedBuffer* pSeed,
1033
                                         uint32_t lenSeed,
1034
                                         SOPC_SC_SecurityKeySet* pks,
1035
                                         uint8_t* genData,
1036
                                         uint32_t lenData,
1037
                                         uint32_t lenKeySign,
1038
                                         uint32_t lenKeyEncr,
1039
                                         uint32_t lenIV);
1040
SOPC_ReturnStatus SOPC_CryptoProvider_DeriveKeySets(const SOPC_CryptoProvider* pProvider,
1041
                                                    const SOPC_ExposedBuffer* pClientNonce,
1042
                                                    uint32_t lenClientNonce,
1043
                                                    const SOPC_ExposedBuffer* pServerNonce,
1044
                                                    uint32_t lenServerNonce,
1045
                                                    SOPC_SC_SecurityKeySet* pClientKeySet,
1046
                                                    SOPC_SC_SecurityKeySet* pServerKeySet)
1047
0
{
1048
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
1049
0
    uint8_t* genData = NULL;
1050
0
    uint32_t lenData = 0;
1051
0
    uint32_t lenKeyEncr = 0, lenKeySign = 0, lenIV = 0;
1052
1053
    // Verify pointers
1054
0
    if (NULL == pProvider || NULL == pClientNonce || NULL == pServerNonce || NULL == pClientKeySet ||
1055
0
        NULL == pServerKeySet)
1056
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1057
1058
0
    if (NULL == pClientKeySet->signKey || NULL == pClientKeySet->encryptKey || NULL == pClientKeySet->initVector)
1059
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1060
1061
0
    if (NULL == pServerKeySet->signKey || NULL == pServerKeySet->encryptKey || NULL == pServerKeySet->initVector)
1062
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1063
1064
    // Calculate expected lengths
1065
0
    if (SOPC_CryptoProvider_DeriveGetLengths(pProvider, &lenKeyEncr, &lenKeySign, &lenIV) != SOPC_STATUS_OK)
1066
0
        return SOPC_STATUS_NOK;
1067
1068
    // Verify lengths
1069
0
    if (SOPC_SecretBuffer_GetLength(pClientKeySet->signKey) != lenKeySign ||
1070
0
        SOPC_SecretBuffer_GetLength(pClientKeySet->encryptKey) != lenKeyEncr ||
1071
0
        SOPC_SecretBuffer_GetLength(pClientKeySet->initVector) != lenIV)
1072
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1073
1074
0
    if (SOPC_SecretBuffer_GetLength(pServerKeySet->signKey) != lenKeySign ||
1075
0
        SOPC_SecretBuffer_GetLength(pServerKeySet->encryptKey) != lenKeyEncr ||
1076
0
        SOPC_SecretBuffer_GetLength(pServerKeySet->initVector) != lenIV)
1077
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1078
1079
    // Allocate buffer for PRF generated data
1080
0
    lenData = lenKeySign + lenKeyEncr + lenIV;
1081
0
    genData = SOPC_Malloc(lenData);
1082
0
    if (NULL == genData)
1083
0
        return SOPC_STATUS_NOK;
1084
1085
    // Derives keyset for the client
1086
0
    status = DeriveKS(pProvider, pServerNonce, lenServerNonce, pClientNonce, lenClientNonce, pClientKeySet, genData,
1087
0
                      lenData, lenKeySign, lenKeyEncr, lenIV);
1088
    // Derives keyset for the server
1089
0
    if (SOPC_STATUS_OK == status)
1090
0
        status = DeriveKS(pProvider, pClientNonce, lenClientNonce, pServerNonce, lenServerNonce, pServerKeySet, genData,
1091
0
                          lenData, lenKeySign, lenKeyEncr, lenIV);
1092
1093
    // Clears and delete
1094
0
    memset(genData, 0, lenData);
1095
0
    SOPC_Free(genData);
1096
1097
0
    return status;
1098
0
}
1099
1100
static inline SOPC_ReturnStatus DeriveKS(const SOPC_CryptoProvider* pProvider,
1101
                                         const SOPC_ExposedBuffer* pSecret,
1102
                                         uint32_t lenSecret,
1103
                                         const SOPC_ExposedBuffer* pSeed,
1104
                                         uint32_t lenSeed,
1105
                                         SOPC_SC_SecurityKeySet* pks,
1106
                                         uint8_t* genData,
1107
                                         uint32_t lenData,
1108
                                         uint32_t lenKeySign,
1109
                                         uint32_t lenKeyEncr,
1110
                                         uint32_t lenIV)
1111
0
{
1112
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
1113
0
    SOPC_ExposedBuffer *pExpEncr = NULL, *pExpSign = NULL, *pExpIV = NULL;
1114
1115
    // Exposes SecretBuffers
1116
0
    pExpEncr = SOPC_SecretBuffer_ExposeModify(pks->encryptKey);
1117
0
    pExpSign = SOPC_SecretBuffer_ExposeModify(pks->signKey);
1118
0
    pExpIV = SOPC_SecretBuffer_ExposeModify(pks->initVector);
1119
1120
    // Verifies exposures
1121
0
    if (NULL == pExpEncr || NULL == pExpSign || NULL == pExpIV)
1122
0
        return SOPC_STATUS_NOK;
1123
1124
    // Generates KeySet
1125
0
    status =
1126
0
        SOPC_CryptoProvider_DerivePseudoRandomData(pProvider, pSecret, lenSecret, pSeed, lenSeed, genData, lenData);
1127
0
    if (SOPC_STATUS_OK == status)
1128
0
    {
1129
0
        memcpy(pExpSign, genData, lenKeySign);
1130
0
        memcpy(pExpEncr, genData + lenKeySign, lenKeyEncr);
1131
0
        memcpy(pExpIV, genData + lenKeySign + lenKeyEncr, lenIV);
1132
0
    }
1133
1134
    // Release ExposedBuffers
1135
0
    SOPC_SecretBuffer_UnexposeModify(pExpEncr, pks->encryptKey);
1136
0
    SOPC_SecretBuffer_UnexposeModify(pExpSign, pks->signKey);
1137
0
    SOPC_SecretBuffer_UnexposeModify(pExpIV, pks->initVector);
1138
1139
0
    return status;
1140
0
}
1141
1142
SOPC_ReturnStatus SOPC_CryptoProvider_DeriveKeySetsClient(const SOPC_CryptoProvider* pProvider,
1143
                                                          const SOPC_SecretBuffer* pClientNonce,
1144
                                                          const SOPC_ExposedBuffer* pServerNonce,
1145
                                                          uint32_t lenServerNonce,
1146
                                                          SOPC_SC_SecurityKeySet* pClientKeySet,
1147
                                                          SOPC_SC_SecurityKeySet* pServerKeySet)
1148
0
{
1149
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
1150
0
    const SOPC_ExposedBuffer* pExpCli = NULL;
1151
1152
0
    if (NULL == pProvider || NULL == pClientNonce || NULL == pServerNonce || NULL == pClientKeySet ||
1153
0
        NULL == pServerKeySet)
1154
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1155
1156
0
    pExpCli = SOPC_SecretBuffer_Expose(pClientNonce);
1157
0
    if (NULL == pExpCli)
1158
0
        status = SOPC_STATUS_INVALID_PARAMETERS;
1159
1160
0
    if (SOPC_STATUS_OK == status)
1161
0
    {
1162
0
        status = SOPC_CryptoProvider_DeriveKeySets(pProvider, pExpCli, SOPC_SecretBuffer_GetLength(pClientNonce),
1163
0
                                                   pServerNonce, lenServerNonce, pClientKeySet, pServerKeySet);
1164
0
    }
1165
1166
0
    SOPC_SecretBuffer_Unexpose(pExpCli, pClientNonce);
1167
1168
0
    return status;
1169
0
}
1170
1171
SOPC_ReturnStatus SOPC_CryptoProvider_DeriveKeySetsServer(const SOPC_CryptoProvider* pProvider,
1172
                                                          const SOPC_ExposedBuffer* pClientNonce,
1173
                                                          uint32_t lenClientNonce,
1174
                                                          SOPC_SecretBuffer* pServerNonce,
1175
                                                          SOPC_SC_SecurityKeySet* pClientKeySet,
1176
                                                          SOPC_SC_SecurityKeySet* pServerKeySet)
1177
0
{
1178
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
1179
0
    const SOPC_ExposedBuffer* pExpSer = NULL;
1180
1181
0
    if (NULL == pProvider || NULL == pClientNonce || NULL == pServerNonce || NULL == pClientKeySet ||
1182
0
        NULL == pServerKeySet)
1183
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1184
1185
0
    pExpSer = SOPC_SecretBuffer_Expose(pServerNonce);
1186
0
    if (NULL == pExpSer)
1187
0
        status = SOPC_STATUS_INVALID_PARAMETERS;
1188
1189
0
    if (SOPC_STATUS_OK == status)
1190
0
    {
1191
0
        status =
1192
0
            SOPC_CryptoProvider_DeriveKeySets(pProvider, pClientNonce, lenClientNonce, pExpSer,
1193
0
                                              SOPC_SecretBuffer_GetLength(pServerNonce), pClientKeySet, pServerKeySet);
1194
0
    }
1195
1196
0
    SOPC_SecretBuffer_Unexpose(pExpSer, pServerNonce);
1197
1198
0
    return status;
1199
0
}
1200
1201
/* ------------------------------------------------------------------------------------------------
1202
 * Asymmetric API
1203
 * ------------------------------------------------------------------------------------------------
1204
 */
1205
1206
SOPC_ReturnStatus SOPC_CryptoProvider_AsymmetricEncrypt(const SOPC_CryptoProvider* pProvider,
1207
                                                        const uint8_t* pInput,
1208
                                                        uint32_t lenInput,
1209
                                                        const SOPC_AsymmetricKey* pKey,
1210
                                                        uint8_t* pOutput,
1211
                                                        uint32_t lenOutput,
1212
                                                        const char** errorReason)
1213
0
{
1214
0
    SOPC_ASSERT(NULL != errorReason);
1215
0
    *errorReason = "";
1216
1217
0
    uint32_t lenOutCalc = 0;
1218
0
    uint32_t lenKey = 0;
1219
1220
0
    if (NULL == pProvider || NULL == pInput || 0 == lenInput || NULL == pKey || NULL == pOutput || 0 == lenOutput)
1221
0
    {
1222
0
        *errorReason = "NULL parameter or 0 length provided";
1223
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1224
0
    }
1225
1226
0
    const SOPC_SecurityPolicy_Config* pPolicy = getCSSecurityPolicyFromProvider(pProvider);
1227
0
    const SOPC_CryptoProfile* pProfile = pPolicy->profile;
1228
0
    if (NULL == pProfile || NULL == pProfile->pFnAsymEncrypt)
1229
0
    {
1230
0
        *errorReason = "invalid cryptographic provider (invalid profile)";
1231
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1232
0
    }
1233
1234
    // Check buffer length
1235
0
    if (SOPC_CryptoProvider_AsymmetricGetLength_Encryption(pProvider, pKey, lenInput, &lenOutCalc) != SOPC_STATUS_OK)
1236
0
    {
1237
0
        *errorReason = "error during computation of encrypted message size from public key";
1238
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1239
0
    }
1240
0
    if (lenOutput != lenOutCalc)
1241
0
    {
1242
0
        *errorReason = "computed encrypted length from public key is not equal to output buffer provided";
1243
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1244
0
    }
1245
1246
    // Check key length
1247
0
    if (SOPC_CryptoProvider_AsymmetricGetLength_KeyBits(pProvider, pKey, &lenKey) != SOPC_STATUS_OK)
1248
0
    {
1249
0
        *errorReason = "error extracting key length from public key";
1250
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1251
0
    }
1252
1253
0
    if (!checkKeyLengthRange(pPolicy, lenKey, errorReason, true))
1254
0
    {
1255
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1256
0
    }
1257
1258
    // We can now proceed
1259
0
    SOPC_ReturnStatus status = pProfile->pFnAsymEncrypt(pProvider, pInput, lenInput, pKey, pOutput);
1260
0
    if (SOPC_STATUS_OK != status)
1261
0
    {
1262
0
        *errorReason = "encryption processing failed (invalid key type or message length)";
1263
0
    }
1264
0
    return status;
1265
0
}
1266
1267
SOPC_ReturnStatus SOPC_CryptoProvider_AsymmetricDecrypt(const SOPC_CryptoProvider* pProvider,
1268
                                                        const uint8_t* pInput,
1269
                                                        uint32_t lenInput,
1270
                                                        const SOPC_AsymmetricKey* pKey,
1271
                                                        uint8_t* pOutput,
1272
                                                        uint32_t lenOutput,
1273
                                                        uint32_t* pLenWritten,
1274
                                                        const char** errorReason)
1275
0
{
1276
0
    SOPC_ASSERT(NULL != errorReason);
1277
0
    *errorReason = "";
1278
1279
0
    uint32_t lenOutCalc = 0;
1280
0
    uint32_t lenKey = 0;
1281
1282
0
    if (NULL == pProvider || NULL == pInput || 0 == lenInput || NULL == pKey || NULL == pOutput || 0 == lenOutput)
1283
0
    {
1284
0
        *errorReason = "NULL parameter or 0 length provided";
1285
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1286
0
    }
1287
1288
0
    const SOPC_SecurityPolicy_Config* pPolicy = getCSSecurityPolicyFromProvider(pProvider);
1289
0
    const SOPC_CryptoProfile* pProfile = pPolicy->profile;
1290
0
    if (NULL == pProfile || NULL == pProfile->pFnAsymDecrypt)
1291
0
    {
1292
0
        *errorReason = "invalid cryptographic provider (invalid profile)";
1293
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1294
0
    }
1295
1296
    // Check buffer length
1297
0
    if (SOPC_CryptoProvider_AsymmetricGetLength_Decryption(pProvider, pKey, lenInput, &lenOutCalc) != SOPC_STATUS_OK)
1298
0
    {
1299
0
        *errorReason = "error during computation of encrypted message size from private key";
1300
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1301
0
    }
1302
0
    if (lenOutput != lenOutCalc)
1303
0
    {
1304
0
        *errorReason = "computed encrypted length from private key is not equal to output buffer provided";
1305
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1306
0
    }
1307
1308
    // Check key length
1309
0
    if (SOPC_CryptoProvider_AsymmetricGetLength_KeyBits(pProvider, pKey, &lenKey) != SOPC_STATUS_OK)
1310
0
    {
1311
0
        *errorReason = "error extracting key length from private key";
1312
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1313
0
    }
1314
1315
0
    if (!checkKeyLengthRange(pPolicy, lenKey, errorReason, false))
1316
0
    {
1317
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1318
0
    }
1319
1320
    // We can now proceed
1321
0
    SOPC_ReturnStatus status = pProfile->pFnAsymDecrypt(pProvider, pInput, lenInput, pKey, pOutput, pLenWritten);
1322
0
    if (SOPC_STATUS_OK != status)
1323
0
    {
1324
0
        *errorReason = "decryption processing failed (invalid key type or message length)";
1325
0
    }
1326
0
    return status;
1327
0
}
1328
1329
/**
1330
 * Asymmetric signature works with asymmetric keys. \p pKey is the local private key.
1331
 * A hash of \p pInput is computed then encrypted with the \p pKey. To verify the signature,
1332
 * one decrypts the \p pSignature with the corresponding public key, computes the hash of \p pInput,
1333
 * and verify that both hashes are the same. Everyone can decrypt the signature,
1334
 * but only the private key could have forged it.
1335
 */
1336
SOPC_ReturnStatus SOPC_CryptoProvider_AsymmetricSign(const SOPC_CryptoProvider* pProvider,
1337
                                                     const uint8_t* pInput,
1338
                                                     uint32_t lenInput,
1339
                                                     const SOPC_AsymmetricKey* pKeyPrivateLocal,
1340
                                                     uint8_t* pSignature,
1341
                                                     uint32_t lenSignature,
1342
                                                     const char** errorReason)
1343
0
{
1344
0
    SOPC_ASSERT(NULL != errorReason);
1345
0
    *errorReason = "";
1346
1347
0
    uint32_t lenSigCalc = 0, lenKey = 0;
1348
1349
0
    if (NULL == pProvider || NULL == pInput || 0 == lenInput || NULL == pKeyPrivateLocal || NULL == pSignature ||
1350
0
        0 == lenSignature)
1351
0
    {
1352
0
        *errorReason = "NULL parameter or 0 length provided";
1353
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1354
0
    }
1355
1356
0
    const SOPC_SecurityPolicy_Config* pPolicy = getCSSecurityPolicyFromProvider(pProvider);
1357
0
    const SOPC_CryptoProfile* pProfile = pPolicy->profile;
1358
0
    if (NULL == pProfile || NULL == pProfile->pFnAsymSign)
1359
0
    {
1360
0
        *errorReason = "invalid cryptographic provider (invalid profile)";
1361
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1362
0
    }
1363
1364
    // Check lengths
1365
0
    if (SOPC_CryptoProvider_AsymmetricGetLength_Signature(pProvider, pKeyPrivateLocal, &lenSigCalc) != SOPC_STATUS_OK)
1366
0
    {
1367
0
        *errorReason = "error during computation of signature size from private key";
1368
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1369
0
    }
1370
0
    if (lenSignature != lenSigCalc)
1371
0
    {
1372
0
        *errorReason = "computed signature length from private key is not equal to the one computed from public key";
1373
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1374
0
    }
1375
0
    if (SOPC_CryptoProvider_AsymmetricGetLength_KeyBits(pProvider, pKeyPrivateLocal, &lenKey) != SOPC_STATUS_OK)
1376
0
    {
1377
0
        *errorReason = "error extracting key length from private key";
1378
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1379
0
    }
1380
1381
0
    if (!checkKeyLengthRange(pPolicy, lenKey, errorReason, false))
1382
0
    {
1383
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1384
0
    }
1385
1386
0
    SOPC_ReturnStatus status = pProfile->pFnAsymSign(pProvider, pInput, lenInput, pKeyPrivateLocal, pSignature);
1387
0
    if (SOPC_STATUS_OK != status)
1388
0
    {
1389
0
        *errorReason = "signature processing failed";
1390
0
    }
1391
0
    return status;
1392
0
}
1393
1394
SOPC_ReturnStatus SOPC_CryptoProvider_AsymmetricVerify(const SOPC_CryptoProvider* pProvider,
1395
                                                       const uint8_t* pInput,
1396
                                                       uint32_t lenInput,
1397
                                                       const SOPC_AsymmetricKey* pKeyRemotePublic,
1398
                                                       const uint8_t* pSignature,
1399
                                                       uint32_t lenSignature,
1400
                                                       const char** errorReason)
1401
0
{
1402
0
    SOPC_ASSERT(NULL != errorReason);
1403
0
    *errorReason = "";
1404
1405
0
    uint32_t lenSigCalc = 0, lenKey = 0;
1406
1407
0
    if (NULL == pProvider || NULL == pInput || 0 == lenInput || NULL == pKeyRemotePublic || NULL == pSignature ||
1408
0
        0 == lenSignature)
1409
0
    {
1410
0
        *errorReason = "NULL parameter or 0 length provided";
1411
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1412
0
    }
1413
1414
0
    const SOPC_SecurityPolicy_Config* pPolicy = getCSSecurityPolicyFromProvider(pProvider);
1415
0
    const SOPC_CryptoProfile* pProfile = pPolicy->profile;
1416
0
    if (NULL == pProfile || NULL == pProfile->pFnAsymVerify)
1417
0
    {
1418
0
        *errorReason = "invalid cryptographic provider (invalid profile)";
1419
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1420
0
    }
1421
1422
    // Check lengths
1423
0
    if (SOPC_CryptoProvider_AsymmetricGetLength_Signature(pProvider, pKeyRemotePublic, &lenSigCalc) != SOPC_STATUS_OK)
1424
0
    {
1425
0
        *errorReason = "error during computation of signature size from public key";
1426
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1427
0
    }
1428
0
    if (lenSignature != lenSigCalc)
1429
0
    {
1430
0
        *errorReason = "computed signature length is not equal to output buffer provided";
1431
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1432
0
    }
1433
0
    if (SOPC_CryptoProvider_AsymmetricGetLength_KeyBits(pProvider, pKeyRemotePublic, &lenKey) != SOPC_STATUS_OK)
1434
0
    {
1435
0
        *errorReason = "error extracting key length from public key";
1436
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1437
0
    }
1438
1439
0
    if (!checkKeyLengthRange(pPolicy, lenKey, errorReason, true))
1440
0
    {
1441
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1442
0
    }
1443
1444
0
    SOPC_ReturnStatus status = pProfile->pFnAsymVerify(pProvider, pInput, lenInput, pKeyRemotePublic, pSignature);
1445
0
    if (SOPC_STATUS_OK != status)
1446
0
    {
1447
0
        *errorReason = "signature processing failed";
1448
0
    }
1449
0
    return status;
1450
0
}
1451
1452
/* ------------------------------------------------------------------------------------------------
1453
 * Certificate validation
1454
 * ------------------------------------------------------------------------------------------------
1455
 */
1456
SOPC_ReturnStatus SOPC_CryptoProvider_Certificate_Validate(const SOPC_CryptoProvider* pProvider,
1457
                                                           SOPC_PKIProvider* pPKI,
1458
                                                           const SOPC_PKI_Type pPKIType,
1459
                                                           const SOPC_CertificateList* pCert,
1460
                                                           uint32_t* error)
1461
0
{
1462
0
    SOPC_ASSERT(NULL != error);
1463
0
    SOPC_ReturnStatus status = SOPC_STATUS_INVALID_PARAMETERS;
1464
1465
    // TODO: where is the key key_pub <-> key_priv association checked?
1466
0
    if (NULL == pProvider || NULL == pPKI || NULL == pCert)
1467
0
    {
1468
0
        return status;
1469
0
    }
1470
1471
0
    const SOPC_SecurityPolicy_Config* pPolicy = getCSSecurityPolicyFromProvider(pProvider);
1472
0
    const SOPC_CryptoProfile* pProfile = pPolicy->profile;
1473
0
    if (NULL == pProfile)
1474
0
    {
1475
0
        return status;
1476
0
    }
1477
1478
0
    SOPC_PKI_Profile* pPKIProfile = NULL;
1479
1480
0
    if (pPolicy->certLen_Thumbprint > 0 && pPolicy->URI_SignAlgo != NULL)
1481
0
    {
1482
0
        status = SOPC_PKIProvider_CreateProfile(pPolicy->uri, &pPKIProfile);
1483
0
    }
1484
0
    else
1485
0
    {
1486
0
        return status;
1487
0
    }
1488
1489
0
    if (SOPC_STATUS_OK == status)
1490
0
    {
1491
0
        status = SOPC_PKIProvider_ProfileSetUsageFromType(pPKIProfile, pPKIType);
1492
0
    }
1493
1494
0
    if (SOPC_STATUS_OK == status)
1495
0
    {
1496
0
        status = SOPC_PKIProvider_ValidateCertificate(pPKI, pCert, pPKIProfile, error);
1497
0
    }
1498
1499
0
    SOPC_PKIProvider_DeleteProfile(&pPKIProfile);
1500
0
    return status;
1501
0
}