Forráskód Böngészése

SecurityPolicy: Pull out common code to a separate compilation unit

Julius Pfrommer 6 éve
szülő
commit
989a081a34

+ 0 - 7
plugins/securityPolicies/ua_securitypolicies.h

@@ -10,7 +10,6 @@
 #define UA_SECURITYPOLICIES_H_
 
 #include "ua_plugin_securitypolicy.h"
-#include <mbedtls/md.h>
 
 _UA_BEGIN_DECLS
 
@@ -41,12 +40,6 @@ UA_SecurityPolicy_Basic256Sha256(UA_SecurityPolicy *policy,
                                  const UA_ByteString localPrivateKey,
                                  const UA_Logger *logger);
 
-/* Internal definitions for reuse between policies */
-UA_StatusCode
-generateKey_sha1p(mbedtls_md_context_t *sha1MdContext,
-                  const UA_ByteString *secret, const UA_ByteString *seed,
-                  UA_ByteString *out);
-
 #endif
 
 _UA_END_DECLS

+ 54 - 217
plugins/securityPolicies/ua_securitypolicy_basic128rsa15.c

@@ -18,6 +18,7 @@
 #include "ua_types.h"
 #include "ua_plugin_pki.h"
 #include "ua_securitypolicies.h"
+#include "ua_securitypolicy_mbedtls_common.h"
 #include "ua_types_generated_handling.h"
 #include "ua_util.h"
 
@@ -28,7 +29,6 @@
  */
 
 #define UA_SECURITYPOLICY_BASIC128RSA15_RSAPADDING_LEN 11
-#define UA_SHA1_LENGTH 20
 #define UA_SECURITYPOLICY_BASIC128RSA15_SYM_KEY_LENGTH 16
 #define UA_BASIC128RSA15_SYM_SIGNING_KEY_LENGTH 16
 #define UA_SECURITYPOLICY_BASIC128RSA15_SYM_ENCRYPTION_BLOCK_SIZE 16
@@ -36,24 +36,6 @@
 #define UA_SECURITYPOLICY_BASIC128RSA15_MINASYMKEYLENGTH 128
 #define UA_SECURITYPOLICY_BASIC128RSA15_MAXASYMKEYLENGTH 256
 
-#define UA_LOG_MBEDERR                                                  \
-    char errBuff[300];                                                  \
-    mbedtls_strerror(mbedErr, errBuff, 300);                            \
-    UA_LOG_WARNING(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY, \
-                   "mbedTLS returned an error: %s", errBuff);           \
-
-#define UA_MBEDTLS_ERRORHANDLING(errorcode)                             \
-    if(mbedErr) {                                                       \
-        UA_LOG_MBEDERR                                                  \
-        retval = errorcode;                                             \
-    }
-
-#define UA_MBEDTLS_ERRORHANDLING_RETURN(errorcode)                      \
-    if(mbedErr) {                                                       \
-        UA_LOG_MBEDERR                                                  \
-        return errorcode;                                               \
-    }
-
 typedef struct {
     const UA_SecurityPolicy *securityPolicy;
     UA_ByteString localCertThumbprint;
@@ -90,26 +72,7 @@ asym_verify_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy,
     if(securityPolicy == NULL || message == NULL || signature == NULL || cc == NULL)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    /* Compute the sha1 hash */
-    unsigned char hash[UA_SHA1_LENGTH];
-#if MBEDTLS_VERSION_NUMBER >= 0x02070000
-    mbedtls_sha1_ret(message->data, message->length, hash);
-#else
-    mbedtls_sha1(message->data, message->length, hash);
-#endif
-
-    /* Set the RSA settings */
-    mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
-    if (!rsaContext)
-        return UA_STATUSCODE_BADINTERNALERROR;
-    mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V15, 0);
-
-    /* Verify */
-    int mbedErr = mbedtls_pk_verify(&cc->remoteCertificate.pk,
-                                    MBEDTLS_MD_SHA1, hash, UA_SHA1_LENGTH,
-                                    signature->data, signature->length);
-    UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADSECURITYCHECKSFAILED);
-    return UA_STATUSCODE_GOOD;
+    return mbedtls_verifySig_sha1(&cc->remoteCertificate, message, signature);
 }
 
 static UA_StatusCode
@@ -120,25 +83,9 @@ asym_sign_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy,
     if(securityPolicy == NULL || message == NULL || signature == NULL || cc == NULL)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    unsigned char hash[UA_SHA1_LENGTH];
-#if MBEDTLS_VERSION_NUMBER >= 0x02070000
-    mbedtls_sha1_ret(message->data, message->length, hash);
-#else
-    mbedtls_sha1(message->data, message->length, hash);
-#endif
-
     Basic128Rsa15_PolicyContext *pc = cc->policyContext;
-    mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(pc->localPrivateKey);
-    mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V15, 0);
-
-    size_t sigLen = 0;
-    int mbedErr = mbedtls_pk_sign(&pc->localPrivateKey,
-                                  MBEDTLS_MD_SHA1, hash,
-                                  UA_SHA1_LENGTH, signature->data,
-                                  &sigLen, mbedtls_ctr_drbg_random,
-                                  &pc->drbgContext);
-    UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADINTERNALERROR);
-    return UA_STATUSCODE_GOOD;
+    return mbedtls_sign_sha1(&pc->localPrivateKey, &pc->drbgContext,
+                             message, signature);
 }
 
 static size_t
@@ -194,10 +141,9 @@ asym_encrypt_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy,
                                          encrypted.length - offset,
                                          mbedtls_ctr_drbg_random,
                                          &pc->drbgContext);
-        UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADINTERNALERROR);
-        if(retval != UA_STATUSCODE_GOOD) {
+        if(mbedErr) {
             UA_ByteString_deleteMembers(&encrypted);
-            return retval;
+            return UA_STATUSCODE_BADINTERNALERROR;
         }
 
         inOffset += plainTextBlockSize;
@@ -218,45 +164,31 @@ asym_decrypt_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy,
     if(securityPolicy == NULL || cc == NULL || data == NULL)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    mbedtls_rsa_context *rsaContext =
-        mbedtls_pk_rsa(cc->policyContext->localPrivateKey);
+    mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(cc->policyContext->localPrivateKey);
     mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V15, 0);
 
     if(data->length % rsaContext->len != 0)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    UA_ByteString decrypted;
-    UA_StatusCode retval = UA_ByteString_allocBuffer(&decrypted, data->length);
-    if(retval != UA_STATUSCODE_GOOD)
-        return retval;
-
-    size_t lenDataToDecrypt = data->length;
     size_t inOffset = 0;
-    size_t offset = 0;
+    size_t outOffset = 0;
     size_t outLength = 0;
-    while(lenDataToDecrypt >= rsaContext->len) {
+    unsigned char buf[512];
+
+    while(inOffset < data->length) {
         int mbedErr = mbedtls_pk_decrypt(&cc->policyContext->localPrivateKey,
                                          data->data + inOffset, rsaContext->len,
-                                         decrypted.data + offset, &outLength,
-                                         decrypted.length - offset, NULL, NULL);
+                                         buf, &outLength, 512, NULL, NULL);
         if(mbedErr)
-            UA_ByteString_deleteMembers(&decrypted); // TODO: Maybe change error macro to jump to cleanup?
-        UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADSECURITYCHECKSFAILED);
+            return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
 
+        memcpy(data->data + outOffset, buf, outLength);
         inOffset += rsaContext->len;
-        offset += outLength;
-        lenDataToDecrypt -= rsaContext->len;
+        outOffset += outLength;
     }
 
-    if(lenDataToDecrypt == 0) {
-        memcpy(data->data, decrypted.data, offset);
-        data->length = offset;
-    } else {
-        retval = UA_STATUSCODE_BADINTERNALERROR;
-    }
-
-    UA_ByteString_deleteMembers(&decrypted);
-    return retval;
+    data->length = outOffset;
+    return UA_STATUSCODE_GOOD;
 }
 
 static size_t
@@ -285,19 +217,7 @@ asym_makeThumbprint_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy,
                                      UA_ByteString *thumbprint) {
     if(securityPolicy == NULL || certificate == NULL || thumbprint == NULL)
         return UA_STATUSCODE_BADINTERNALERROR;
-
-    if(UA_ByteString_equal(certificate, &UA_BYTESTRING_NULL))
-        return UA_STATUSCODE_BADINTERNALERROR;
-
-    if(thumbprint->length != UA_SHA1_LENGTH)
-        return UA_STATUSCODE_BADINTERNALERROR;
-
-#if MBEDTLS_VERSION_NUMBER >= 0x02070000
-    mbedtls_sha1_ret(certificate->data, certificate->length, thumbprint->data);
-#else
-    mbedtls_sha1(certificate->data, certificate->length, thumbprint->data);
-#endif
-    return UA_STATUSCODE_GOOD;
+    return mbedtls_thumbprint_sha1(certificate, thumbprint);
 }
 
 static UA_StatusCode
@@ -317,14 +237,6 @@ asymmetricModule_compareCertificateThumbprint_sp_basic128rsa15(const UA_Security
 /* SymmetricModule */
 /*******************/
 
-static void
-md_hmac(mbedtls_md_context_t *context, const UA_ByteString *key,
-        const UA_ByteString *in, unsigned char out[20]) {
-    mbedtls_md_hmac_starts(context, key->data, key->length);
-    mbedtls_md_hmac_update(context, in->data, in->length);
-    mbedtls_md_hmac_finish(context, out);
-}
-
 static UA_StatusCode
 sym_verify_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy,
                             Basic128Rsa15_ChannelContext *cc,
@@ -344,7 +256,7 @@ sym_verify_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy,
         (Basic128Rsa15_PolicyContext *)securityPolicy->policyContext;
 
     unsigned char mac[UA_SHA1_LENGTH];
-    md_hmac(&pc->sha1MdContext, &cc->remoteSymSigningKey, message, mac);
+    mbedtls_hmac(&pc->sha1MdContext, &cc->remoteSymSigningKey, message, mac);
 
     /* Compare with Signature */
     if(!UA_constantTimeEqual(signature->data, mac, UA_SHA1_LENGTH))
@@ -360,8 +272,8 @@ sym_sign_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy,
     if(signature->length != UA_SHA1_LENGTH)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    md_hmac(&cc->policyContext->sha1MdContext, &cc->localSymSigningKey,
-            message, signature->data);
+    mbedtls_hmac(&cc->policyContext->sha1MdContext, &cc->localSymSigningKey,
+                 message, signature->data);
     return UA_STATUSCODE_GOOD;
 }
 
@@ -420,7 +332,8 @@ sym_encrypt_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy,
     unsigned int keylength = (unsigned int)(cc->localSymEncryptingKey.length * 8);
     mbedtls_aes_context aesContext;
     int mbedErr = mbedtls_aes_setkey_enc(&aesContext, cc->localSymEncryptingKey.data, keylength);
-    UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADINTERNALERROR);
+    if(mbedErr)
+        return UA_STATUSCODE_BADINTERNALERROR;
 
     UA_ByteString ivCopy;
     UA_StatusCode retval = UA_ByteString_copy(&cc->localSymIv, &ivCopy);
@@ -429,7 +342,8 @@ sym_encrypt_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy,
 
     mbedErr = mbedtls_aes_crypt_cbc(&aesContext, MBEDTLS_AES_ENCRYPT, data->length,
                                     ivCopy.data, data->data, data->data);
-    UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADINTERNALERROR);
+    if(mbedErr)
+        retval = UA_STATUSCODE_BADINTERNALERROR;
     UA_ByteString_deleteMembers(&ivCopy);
     return retval;
 }
@@ -441,8 +355,8 @@ sym_decrypt_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy,
     if(securityPolicy == NULL || cc == NULL || data == NULL)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    size_t encryptionBlockSize =
-        securityPolicy->symmetricModule.cryptoModule.encryptionAlgorithm.getRemoteBlockSize(securityPolicy, cc);
+    size_t encryptionBlockSize = securityPolicy->symmetricModule.cryptoModule.
+        encryptionAlgorithm.getRemoteBlockSize(securityPolicy, cc);
 
     if(cc->remoteSymIv.length != encryptionBlockSize)
         return UA_STATUSCODE_BADINTERNALERROR;
@@ -456,7 +370,8 @@ sym_decrypt_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy,
     unsigned int keylength = (unsigned int)(cc->remoteSymEncryptingKey.length * 8);
     mbedtls_aes_context aesContext;
     int mbedErr = mbedtls_aes_setkey_dec(&aesContext, cc->remoteSymEncryptingKey.data, keylength);
-    UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADINTERNALERROR);
+    if(mbedErr)
+        return UA_STATUSCODE_BADINTERNALERROR;
 
     UA_ByteString ivCopy;
     UA_StatusCode retval = UA_ByteString_copy(&cc->remoteSymIv, &ivCopy);
@@ -465,91 +380,12 @@ sym_decrypt_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy,
 
     mbedErr = mbedtls_aes_crypt_cbc(&aesContext, MBEDTLS_AES_DECRYPT, data->length,
                                     ivCopy.data, data->data, data->data);
-    UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADINTERNALERROR);
+    if(mbedErr)
+        retval = UA_STATUSCODE_BADINTERNALERROR;
     UA_ByteString_deleteMembers(&ivCopy);
     return retval;
 }
 
-static void
-swapBuffers(UA_ByteString *const bufA, UA_ByteString *const bufB) {
-    UA_ByteString tmp = *bufA;
-    *bufA = *bufB;
-    *bufB = tmp;
-}
-
-UA_StatusCode
-generateKey_sha1p(mbedtls_md_context_t *sha1MdContext,
-                  const UA_ByteString *secret, const UA_ByteString *seed,
-                  UA_ByteString *out) {
-    size_t hashLen = 0;
-    const mbedtls_md_info_t *mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
-    hashLen = (size_t)mbedtls_md_get_size(mdInfo);
-
-    UA_ByteString A_and_seed;
-    UA_ByteString_allocBuffer(&A_and_seed, hashLen + seed->length);
-    memcpy(A_and_seed.data + hashLen, seed->data, seed->length);
-
-    UA_ByteString ANext_and_seed;
-    UA_ByteString_allocBuffer(&ANext_and_seed, hashLen + seed->length);
-    memcpy(ANext_and_seed.data + hashLen, seed->data, seed->length);
-
-    UA_ByteString A = {
-        hashLen,
-        A_and_seed.data
-    };
-
-    UA_ByteString ANext = {
-        hashLen,
-        ANext_and_seed.data
-    };
-
-    md_hmac(sha1MdContext, secret, seed, A.data);
-
-    UA_StatusCode retval = 0;
-    for(size_t offset = 0; offset < out->length; offset += hashLen) {
-        UA_ByteString outSegment = {
-            hashLen,
-            out->data + offset
-        };
-        UA_Boolean bufferAllocated = UA_FALSE;
-        // Not enough room in out buffer to write the hash.
-        if(offset + hashLen > out->length) {
-            outSegment.data = NULL;
-            outSegment.length = 0;
-            retval = UA_ByteString_allocBuffer(&outSegment, hashLen);
-            if(retval != UA_STATUSCODE_GOOD) {
-                UA_ByteString_deleteMembers(&A_and_seed);
-                UA_ByteString_deleteMembers(&ANext_and_seed);
-                return retval;
-            }
-            bufferAllocated = UA_TRUE;
-        }
-
-        md_hmac(sha1MdContext, secret, &A_and_seed, outSegment.data);
-        md_hmac(sha1MdContext, secret, &A, ANext.data);
-
-        if(retval != UA_STATUSCODE_GOOD) {
-            if(bufferAllocated)
-                UA_ByteString_deleteMembers(&outSegment);
-            UA_ByteString_deleteMembers(&A_and_seed);
-            UA_ByteString_deleteMembers(&ANext_and_seed);
-            return retval;
-        }
-
-        if(bufferAllocated) {
-            memcpy(out->data + offset, outSegment.data, out->length - offset);
-            UA_ByteString_deleteMembers(&outSegment);
-        }
-
-        swapBuffers(&ANext_and_seed, &A_and_seed);
-        swapBuffers(&ANext, &A);
-    }
-
-    UA_ByteString_deleteMembers(&A_and_seed);
-    UA_ByteString_deleteMembers(&ANext_and_seed);
-    return UA_STATUSCODE_GOOD;
-}
-
 static UA_StatusCode
 sym_generateKey_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy,
                                  const UA_ByteString *secret, const UA_ByteString *seed,
@@ -560,7 +396,7 @@ sym_generateKey_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy,
     Basic128Rsa15_PolicyContext *pc =
         (Basic128Rsa15_PolicyContext *)securityPolicy->policyContext;
 
-    return generateKey_sha1p(&pc->sha1MdContext, secret, seed, out);
+    return mbedtls_generateKey(&pc->sha1MdContext, secret, seed, out);
 }
 
 static UA_StatusCode
@@ -569,11 +405,12 @@ sym_generateNonce_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy,
     if(securityPolicy == NULL || securityPolicy->policyContext == NULL || out == NULL)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    Basic128Rsa15_PolicyContext *data =
+    Basic128Rsa15_PolicyContext *pc =
         (Basic128Rsa15_PolicyContext *)securityPolicy->policyContext;
 
-    int mbedErr = mbedtls_ctr_drbg_random(&data->drbgContext, out->data, out->length);
-    UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADUNEXPECTEDERROR);
+    int mbedErr = mbedtls_ctr_drbg_random(&pc->drbgContext, out->data, out->length);
+    if(mbedErr)
+        return UA_STATUSCODE_BADUNEXPECTEDERROR;
 
     return UA_STATUSCODE_GOOD;
 }
@@ -589,12 +426,11 @@ parseRemoteCertificate_sp_basic128rsa15(Basic128Rsa15_ChannelContext *cc,
     if(remoteCertificate == NULL || cc == NULL)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    const UA_SecurityPolicy *securityPolicy = cc->policyContext->securityPolicy;
-
     /* Parse the certificate */
     int mbedErr = mbedtls_x509_crt_parse(&cc->remoteCertificate, remoteCertificate->data,
                                          remoteCertificate->length);
-    UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADSECURITYCHECKSFAILED);
+    if(mbedErr)
+        return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
 
     /* Check the key length */
     mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
@@ -723,15 +559,11 @@ channelContext_compareCertificate_sp_basic128rsa15(const Basic128Rsa15_ChannelCo
     if(cc == NULL || certificate == NULL)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    const UA_SecurityPolicy *securityPolicy = cc->policyContext->securityPolicy;
-
     mbedtls_x509_crt cert;
     mbedtls_x509_crt_init(&cert);
     int mbedErr = mbedtls_x509_crt_parse(&cert, certificate->data, certificate->length);
-    if(mbedErr) {
-        UA_LOG_MBEDERR;
+    if(mbedErr)
         return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
-    }
 
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
     if(cert.raw.len != cc->remoteCertificate.raw.len ||
@@ -796,9 +628,10 @@ updateCertificateAndPrivateKey_sp_basic128rsa15(UA_SecurityPolicy *securityPolic
     int mbedErr = mbedtls_pk_parse_key(&pc->localPrivateKey,
                                        newPrivateKey.data, newPrivateKey.length,
                                        NULL, 0);
-    UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADSECURITYCHECKSFAILED);
-    if(retval != UA_STATUSCODE_GOOD)
+    if(mbedErr) {
+        retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
         goto error;
+    }
 
     retval = asym_makeThumbprint_sp_basic128rsa15(pc->securityPolicy,
                                                   &securityPolicy->localCertificate,
@@ -842,34 +675,38 @@ policyContext_newContext_sp_basic128rsa15(UA_SecurityPolicy *securityPolicy,
     /* Initialized the message digest */
     const mbedtls_md_info_t *const mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
     int mbedErr = mbedtls_md_setup(&pc->sha1MdContext, mdInfo, MBEDTLS_MD_SHA1);
-    UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADOUTOFMEMORY);
-    if(retval != UA_STATUSCODE_GOOD)
+    if(mbedErr) {
+        retval = UA_STATUSCODE_BADOUTOFMEMORY;
         goto error;
+    }
 
     /* Add the system entropy source */
     mbedErr = mbedtls_entropy_add_source(&pc->entropyContext,
                                          mbedtls_platform_entropy_poll, NULL, 0,
                                          MBEDTLS_ENTROPY_SOURCE_STRONG);
-    UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADSECURITYCHECKSFAILED);
-    if(retval != UA_STATUSCODE_GOOD)
+    if(mbedErr) {
+        retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
         goto error;
+    }
 
     /* Seed the RNG */
     char *personalization = "open62541-drbg";
     mbedErr = mbedtls_ctr_drbg_seed(&pc->drbgContext, mbedtls_entropy_func,
                                     &pc->entropyContext,
                                     (const unsigned char *)personalization, 14);
-    UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADSECURITYCHECKSFAILED);
-    if(retval != UA_STATUSCODE_GOOD)
+    if(mbedErr) {
+        retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
         goto error;
+    }
 
     /* Set the private key */
     mbedErr = mbedtls_pk_parse_key(&pc->localPrivateKey,
                                    localPrivateKey.data, localPrivateKey.length,
                                    NULL, 0);
-    UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADSECURITYCHECKSFAILED);
-    if(retval != UA_STATUSCODE_GOOD)
+    if(mbedErr) {
+        retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
         goto error;
+    }
 
     /* Set the local certificate thumbprint */
     retval = UA_ByteString_allocBuffer(&pc->localCertThumbprint, UA_SHA1_LENGTH);

+ 51 - 212
plugins/securityPolicies/ua_securitypolicy_basic256.c

@@ -7,9 +7,6 @@
  */
 
 #include <mbedtls/aes.h>
-#include <mbedtls/md.h>
-#include <mbedtls/x509_crt.h>
-#include <mbedtls/ctr_drbg.h>
 #include <mbedtls/entropy.h>
 #include <mbedtls/entropy_poll.h>
 #include <mbedtls/error.h>
@@ -19,6 +16,7 @@
 #include "ua_types.h"
 #include "ua_plugin_pki.h"
 #include "ua_securitypolicies.h"
+#include "ua_securitypolicy_mbedtls_common.h"
 #include "ua_types_generated_handling.h"
 #include "ua_util.h"
 
@@ -37,24 +35,6 @@
 #define UA_SECURITYPOLICY_BASIC256_MINASYMKEYLENGTH 128
 #define UA_SECURITYPOLICY_BASIC256_MAXASYMKEYLENGTH 256
 
-#define UA_LOG_MBEDERR                                                  \
-    char errBuff[300];                                                  \
-    mbedtls_strerror(mbedErr, errBuff, 300);                            \
-    UA_LOG_WARNING(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY, \
-                   "mbedTLS returned an error: %s", errBuff);           \
-
-#define UA_MBEDTLS_ERRORHANDLING(errorcode)                             \
-    if(mbedErr) {                                                       \
-        UA_LOG_MBEDERR                                                  \
-        retval = errorcode;                                             \
-    }
-
-#define UA_MBEDTLS_ERRORHANDLING_RETURN(errorcode)                      \
-    if(mbedErr) {                                                       \
-        UA_LOG_MBEDERR                                                  \
-        return errorcode;                                               \
-    }
-
 typedef struct {
     const UA_SecurityPolicy *securityPolicy;
     UA_ByteString localCertThumbprint;
@@ -92,31 +72,7 @@ asym_verify_sp_basic256(const UA_SecurityPolicy *securityPolicy,
     if(securityPolicy == NULL || message == NULL || signature == NULL || cc == NULL)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    unsigned char hash[UA_SHA1_LENGTH];
-#if MBEDTLS_VERSION_NUMBER >= 0x02070000
-    // TODO check return status
-    mbedtls_sha1_ret(message->data, message->length, hash);
-#else
-    mbedtls_sha1(message->data, message->length, hash, 0);
-#endif
-
-    /* Set the RSA settings */
-    mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
-    mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_SHA1);
-
-    /* For RSA keys, the default padding type is PKCS#1 v1.5 in mbedtls_pk_verify() */
-    /* Alternatively, use more specific function mbedtls_rsa_rsassa_pkcs1_v15_verify(), i.e. */
-    /* int mbedErr = mbedtls_rsa_rsassa_pkcs1_v15_verify(rsaContext, NULL, NULL,
-                                                         MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA256,
-                                                         UA_SHA256_LENGTH, hash,
-                                                         signature->data); */
-
-    int mbedErr = mbedtls_pk_verify(&cc->remoteCertificate.pk,
-                                    MBEDTLS_MD_SHA1, hash, UA_SHA1_LENGTH,
-                                    signature->data, signature->length);
-
-    UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADSECURITYCHECKSFAILED);
-    return UA_STATUSCODE_GOOD;
+    return mbedtls_verifySig_sha1(&cc->remoteCertificate, message, signature);
 }
 
 /* AsymmetricSignatureAlgorithm_RSA-PKCS15-SHA2-256 */
@@ -128,29 +84,9 @@ asym_sign_sp_basic256(const UA_SecurityPolicy *securityPolicy,
     if(securityPolicy == NULL || message == NULL || signature == NULL || cc == NULL)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    unsigned char hash[UA_SHA1_LENGTH];
-#if MBEDTLS_VERSION_NUMBER >= 0x02070000
-    // TODO check return status
-    mbedtls_sha1_ret(message->data, message->length, hash);
-#else
-    mbedtls_sha1(message->data, message->length, hash);
-#endif
-
     Basic256_PolicyContext *pc = cc->policyContext;
-    mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(pc->localPrivateKey);
-    mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_SHA1);
-
-    size_t sigLen = 0;
-
-    /* For RSA keys, the default padding type is PKCS#1 v1.5 in mbedtls_pk_sign */
-    /* Alternatively use more specific function mbedtls_rsa_rsassa_pkcs1_v15_sign() */
-    int mbedErr = mbedtls_pk_sign(&pc->localPrivateKey,
-                                  MBEDTLS_MD_SHA1, hash,
-                                  UA_SHA1_LENGTH, signature->data,
-                                  &sigLen, mbedtls_ctr_drbg_random,
-                                  &pc->drbgContext);
-    UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADINTERNALERROR);
-    return UA_STATUSCODE_GOOD;
+    return mbedtls_sign_sha1(&pc->localPrivateKey, &pc->drbgContext,
+                             message, signature);
 }
 
 static size_t
@@ -158,7 +94,6 @@ asym_getLocalSignatureSize_sp_basic256(const UA_SecurityPolicy *securityPolicy,
                                        const Basic256_ChannelContext *cc) {
     if(securityPolicy == NULL || cc == NULL)
         return 0;
-
     return mbedtls_pk_rsa(cc->policyContext->localPrivateKey)->len;
 }
 
@@ -167,7 +102,6 @@ asym_getRemoteSignatureSize_sp_basic256(const UA_SecurityPolicy *securityPolicy,
                                         const Basic256_ChannelContext *cc) {
     if(securityPolicy == NULL || cc == NULL)
         return 0;
-
     return mbedtls_pk_rsa(cc->remoteCertificate.pk)->len;
 }
 
@@ -182,100 +116,22 @@ asym_encrypt_sp_basic256(const UA_SecurityPolicy *securityPolicy,
     const size_t plainTextBlockSize = securityPolicy->asymmetricModule.cryptoModule.
         encryptionAlgorithm.getRemotePlainTextBlockSize(securityPolicy, cc);
 
-    if(data->length % plainTextBlockSize != 0)
-        return UA_STATUSCODE_BADINTERNALERROR;
-
     mbedtls_rsa_context *remoteRsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
     mbedtls_rsa_set_padding(remoteRsaContext, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA1);
 
-    UA_ByteString encrypted;
-    const size_t bufferOverhead =
-        UA_SecurityPolicy_getRemoteAsymEncryptionBufferLengthOverhead(securityPolicy, cc, data->length);
-    UA_StatusCode retval = UA_ByteString_allocBuffer(&encrypted, data->length + bufferOverhead);
-    if(retval != UA_STATUSCODE_GOOD)
-        return retval;
-
-    size_t lenDataToEncrypt = data->length;
-    size_t inOffset = 0;
-    size_t offset = 0;
-    const unsigned char *label = NULL;
-    Basic256_PolicyContext *pc = cc->policyContext;
-    while(lenDataToEncrypt >= plainTextBlockSize) {
-        int mbedErr = mbedtls_rsa_rsaes_oaep_encrypt(remoteRsaContext, mbedtls_ctr_drbg_random,
-                                                     &pc->drbgContext, MBEDTLS_RSA_PUBLIC,
-                                                     label, 0, plainTextBlockSize,
-                                                     data->data + inOffset, encrypted.data + offset);
-
-        UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADINTERNALERROR);
-        if(retval != UA_STATUSCODE_GOOD) {
-            UA_ByteString_deleteMembers(&encrypted);
-            return retval;
-        }
-
-        inOffset += plainTextBlockSize;
-        offset += remoteRsaContext->len;
-        lenDataToEncrypt -= plainTextBlockSize;
-    }
-
-    memcpy(data->data, encrypted.data, offset);
-    UA_ByteString_deleteMembers(&encrypted);
-
-    return UA_STATUSCODE_GOOD;
+    return mbedtls_encrypt_rsaOaep(remoteRsaContext, &cc->policyContext->drbgContext,
+                                   data, plainTextBlockSize);
 }
 
 /* AsymmetricEncryptionAlgorithm_RSA-OAEP-SHA1 */
 static UA_StatusCode
 asym_decrypt_sp_basic256(const UA_SecurityPolicy *securityPolicy,
-                               Basic256_ChannelContext *cc,
-                               UA_ByteString *data) {
+                         Basic256_ChannelContext *cc,
+                         UA_ByteString *data) {
     if(securityPolicy == NULL || cc == NULL || data == NULL)
         return UA_STATUSCODE_BADINTERNALERROR;
-
-    mbedtls_rsa_context *rsaContext =
-        mbedtls_pk_rsa(cc->policyContext->localPrivateKey);
-
-    mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA1);
-
-    if(data->length % rsaContext->len != 0)
-        return UA_STATUSCODE_BADINTERNALERROR;
-
-    UA_ByteString decrypted;
-    UA_StatusCode retval = UA_ByteString_allocBuffer(&decrypted, data->length);
-    if(retval != UA_STATUSCODE_GOOD)
-        return retval;
-
-    size_t lenDataToDecrypt = data->length;
-    size_t inOffset = 0;
-    size_t offset = 0;
-    size_t outLength = 0;
-    const unsigned char *label = NULL;
-    Basic256_PolicyContext *pc = cc->policyContext;
-
-    while(lenDataToDecrypt >= rsaContext->len) {
-        int mbedErr = mbedtls_rsa_rsaes_oaep_decrypt(rsaContext, mbedtls_ctr_drbg_random,
-                                                     &pc->drbgContext, MBEDTLS_RSA_PRIVATE,
-                                                     label, 0, &outLength,
-                                                     data->data + inOffset,
-                                                     decrypted.data + offset,
-                                                     decrypted.length - offset);
-        if(mbedErr)
-            UA_ByteString_deleteMembers(&decrypted); // TODO: Maybe change error macro to jump to cleanup?
-        UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADSECURITYCHECKSFAILED);
-
-        inOffset += rsaContext->len;
-        offset += outLength;
-        lenDataToDecrypt -= rsaContext->len;
-    }
-
-    if(lenDataToDecrypt == 0) {
-        memcpy(data->data, decrypted.data, offset);
-        data->length = offset;
-    } else {
-        retval = UA_STATUSCODE_BADINTERNALERROR;
-    }
-
-    UA_ByteString_deleteMembers(&decrypted);
-    return retval;
+    return mbedtls_decrypt_rsaOaep(&cc->policyContext->localPrivateKey,
+                                   &cc->policyContext->drbgContext, data);
 }
 
 static size_t
@@ -304,20 +160,7 @@ asym_makeThumbprint_sp_basic256(const UA_SecurityPolicy *securityPolicy,
                                 UA_ByteString *thumbprint) {
     if(securityPolicy == NULL || certificate == NULL || thumbprint == NULL)
         return UA_STATUSCODE_BADINTERNALERROR;
-
-    if(UA_ByteString_equal(certificate, &UA_BYTESTRING_NULL))
-        return UA_STATUSCODE_BADINTERNALERROR;
-
-    if(thumbprint->length != UA_SHA1_LENGTH)
-        return UA_STATUSCODE_BADINTERNALERROR;
-
-    /* The certificate thumbprint is always a 20 bit sha1 hash, see Part 4 of the Specification. */
-#if MBEDTLS_VERSION_NUMBER >= 0x02070000
-    mbedtls_sha1_ret(certificate->data, certificate->length, thumbprint->data);
-#else
-    mbedtls_sha1(certificate->data, certificate->length, thumbprint->data);
-#endif
-    return UA_STATUSCODE_GOOD;
+    return mbedtls_thumbprint_sha1(certificate, thumbprint);
 }
 
 static UA_StatusCode
@@ -337,14 +180,6 @@ asymmetricModule_compareCertificateThumbprint_sp_basic256(const UA_SecurityPolic
 /* SymmetricModule */
 /*******************/
 
-static void
-md_hmac_Basic256(mbedtls_md_context_t *context, const UA_ByteString *key,
-                 const UA_ByteString *in, unsigned char out[32]) {
-    mbedtls_md_hmac_starts(context, key->data, key->length);
-    mbedtls_md_hmac_update(context, in->data, in->length);
-    mbedtls_md_hmac_finish(context, out);
-}
-
 static UA_StatusCode
 sym_verify_sp_basic256(const UA_SecurityPolicy *securityPolicy,
                        Basic256_ChannelContext *cc,
@@ -364,7 +199,7 @@ sym_verify_sp_basic256(const UA_SecurityPolicy *securityPolicy,
         (Basic256_PolicyContext *)securityPolicy->policyContext;
     
     unsigned char mac[UA_SHA1_LENGTH];
-    md_hmac_Basic256(&pc->sha1MdContext, &cc->remoteSymSigningKey, message, mac);
+    mbedtls_hmac(&pc->sha1MdContext, &cc->remoteSymSigningKey, message, mac);
 
     /* Compare with Signature */
     if(!UA_constantTimeEqual(signature->data, mac, UA_SHA1_LENGTH))
@@ -380,8 +215,8 @@ sym_sign_sp_basic256(const UA_SecurityPolicy *securityPolicy,
     if(signature->length != UA_SHA1_LENGTH)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    md_hmac_Basic256(&cc->policyContext->sha1MdContext, &cc->localSymSigningKey,
-                     message, signature->data);
+    mbedtls_hmac(&cc->policyContext->sha1MdContext, &cc->localSymSigningKey,
+                 message, signature->data);
     return UA_STATUSCODE_GOOD;
 }
 
@@ -442,7 +277,8 @@ sym_encrypt_sp_basic256(const UA_SecurityPolicy *securityPolicy,
     unsigned int keylength = (unsigned int)(cc->localSymEncryptingKey.length * 8);
     mbedtls_aes_context aesContext;
     int mbedErr = mbedtls_aes_setkey_enc(&aesContext, cc->localSymEncryptingKey.data, keylength);
-    UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADINTERNALERROR);
+    if(mbedErr)
+        return UA_STATUSCODE_BADINTERNALERROR;
 
     UA_ByteString ivCopy;
     UA_StatusCode retval = UA_ByteString_copy(&cc->localSymIv, &ivCopy);
@@ -451,7 +287,8 @@ sym_encrypt_sp_basic256(const UA_SecurityPolicy *securityPolicy,
 
     mbedErr = mbedtls_aes_crypt_cbc(&aesContext, MBEDTLS_AES_ENCRYPT, data->length,
                                     ivCopy.data, data->data, data->data);
-    UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADINTERNALERROR);
+    if(mbedErr)
+        retval = UA_STATUSCODE_BADINTERNALERROR;
     UA_ByteString_deleteMembers(&ivCopy);
     return retval;
 }
@@ -479,7 +316,8 @@ sym_decrypt_sp_basic256(const UA_SecurityPolicy *securityPolicy,
     unsigned int keylength = (unsigned int)(cc->remoteSymEncryptingKey.length * 8);
     mbedtls_aes_context aesContext;
     int mbedErr = mbedtls_aes_setkey_dec(&aesContext, cc->remoteSymEncryptingKey.data, keylength);
-    UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADINTERNALERROR);
+    if(mbedErr)
+        return UA_STATUSCODE_BADINTERNALERROR;
 
     UA_ByteString ivCopy;
     UA_StatusCode retval = UA_ByteString_copy(&cc->remoteSymIv, &ivCopy);
@@ -488,7 +326,8 @@ sym_decrypt_sp_basic256(const UA_SecurityPolicy *securityPolicy,
 
     mbedErr = mbedtls_aes_crypt_cbc(&aesContext, MBEDTLS_AES_DECRYPT, data->length,
                                     ivCopy.data, data->data, data->data);
-    UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADINTERNALERROR);
+    if(mbedErr)
+        retval = UA_STATUSCODE_BADINTERNALERROR;
     UA_ByteString_deleteMembers(&ivCopy);
     return retval;
 }
@@ -503,7 +342,7 @@ sym_generateKey_sp_basic256(const UA_SecurityPolicy *securityPolicy,
     Basic256_PolicyContext *pc =
         (Basic256_PolicyContext *)securityPolicy->policyContext;
 
-    return generateKey_sha1p(&pc->sha1MdContext, secret, seed, out);
+    return mbedtls_generateKey(&pc->sha1MdContext, secret, seed, out);
 }
 
 static UA_StatusCode
@@ -512,11 +351,12 @@ sym_generateNonce_sp_basic256(const UA_SecurityPolicy *securityPolicy,
     if(securityPolicy == NULL || securityPolicy->policyContext == NULL || out == NULL)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    Basic256_PolicyContext *data =
+    Basic256_PolicyContext *pc =
         (Basic256_PolicyContext *)securityPolicy->policyContext;
 
-    int mbedErr = mbedtls_ctr_drbg_random(&data->drbgContext, out->data, out->length);
-    UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADUNEXPECTEDERROR);
+    int mbedErr = mbedtls_ctr_drbg_random(&pc->drbgContext, out->data, out->length);
+    if(mbedErr)
+        return UA_STATUSCODE_BADUNEXPECTEDERROR;
 
     return UA_STATUSCODE_GOOD;
 }
@@ -532,12 +372,11 @@ parseRemoteCertificate_sp_basic256(Basic256_ChannelContext *cc,
     if(remoteCertificate == NULL || cc == NULL)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    const UA_SecurityPolicy *securityPolicy = cc->policyContext->securityPolicy;
-
     /* Parse the certificate */
     int mbedErr = mbedtls_x509_crt_parse(&cc->remoteCertificate, remoteCertificate->data,
                                          remoteCertificate->length);
-    UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADSECURITYCHECKSFAILED);
+    if(mbedErr)
+        return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
 
     /* Check the key length */
     mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
@@ -666,15 +505,11 @@ channelContext_compareCertificate_sp_basic256(const Basic256_ChannelContext *cc,
     if(cc == NULL || certificate == NULL)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    const UA_SecurityPolicy *securityPolicy = cc->policyContext->securityPolicy;
-
     mbedtls_x509_crt cert;
     mbedtls_x509_crt_init(&cert);
     int mbedErr = mbedtls_x509_crt_parse(&cert, certificate->data, certificate->length);
-    if(mbedErr) {
-        UA_LOG_MBEDERR;
+    if(mbedErr)
         return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
-    }
 
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
     if(cert.raw.len != cc->remoteCertificate.raw.len ||
@@ -722,13 +557,13 @@ updateCertificateAndPrivateKey_sp_basic256(UA_SecurityPolicy *securityPolicy,
     if(securityPolicy->policyContext == NULL)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    Basic256_PolicyContext *pc =
-            (Basic256_PolicyContext *) securityPolicy->policyContext;
+    Basic256_PolicyContext *pc = (Basic256_PolicyContext *)
+        securityPolicy->policyContext;
 
     UA_ByteString_deleteMembers(&securityPolicy->localCertificate);
 
-    UA_StatusCode retval =
-            UA_ByteString_allocBuffer(&securityPolicy->localCertificate, newCertificate.length + 1);
+    UA_StatusCode retval = UA_ByteString_allocBuffer(&securityPolicy->localCertificate,
+                                                     newCertificate.length + 1);
     if(retval != UA_STATUSCODE_GOOD)
         return retval;
     memcpy(securityPolicy->localCertificate.data, newCertificate.data, newCertificate.length);
@@ -741,9 +576,10 @@ updateCertificateAndPrivateKey_sp_basic256(UA_SecurityPolicy *securityPolicy,
     int mbedErr = mbedtls_pk_parse_key(&pc->localPrivateKey,
                                        newPrivateKey.data, newPrivateKey.length,
                                        NULL, 0);
-    UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADSECURITYCHECKSFAILED);
-    if(retval != UA_STATUSCODE_GOOD)
+    if(mbedErr) {
+        retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
         goto error;
+    }
 
     retval = asym_makeThumbprint_sp_basic256(pc->securityPolicy,
                                              &securityPolicy->localCertificate,
@@ -787,34 +623,37 @@ policyContext_newContext_sp_basic256(UA_SecurityPolicy *securityPolicy,
     /* Initialized the message digest */
     const mbedtls_md_info_t *mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
     int mbedErr = mbedtls_md_setup(&pc->sha1MdContext, mdInfo, MBEDTLS_MD_SHA1);
-    UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADOUTOFMEMORY);
-    if(retval != UA_STATUSCODE_GOOD)
+    if(mbedErr) {
+        retval = UA_STATUSCODE_BADOUTOFMEMORY;
         goto error;
+    }
 
     /* Add the system entropy source */
     mbedErr = mbedtls_entropy_add_source(&pc->entropyContext,
                                          mbedtls_platform_entropy_poll, NULL, 0,
                                          MBEDTLS_ENTROPY_SOURCE_STRONG);
-    UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADSECURITYCHECKSFAILED);
-    if(retval != UA_STATUSCODE_GOOD)
+    if(mbedErr) {
+        retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
         goto error;
+    }
 
     /* Seed the RNG */
     char *personalization = "open62541-drbg";
     mbedErr = mbedtls_ctr_drbg_seed(&pc->drbgContext, mbedtls_entropy_func,
                                     &pc->entropyContext,
                                     (const unsigned char *)personalization, 14);
-    UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADSECURITYCHECKSFAILED);
-    if(retval != UA_STATUSCODE_GOOD)
+    if(mbedErr) {
+        retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
         goto error;
+    }
 
     /* Set the private key */
-    mbedErr = mbedtls_pk_parse_key(&pc->localPrivateKey,
-                                   localPrivateKey.data, localPrivateKey.length,
-                                   NULL, 0);
-    UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADSECURITYCHECKSFAILED);
-    if(retval != UA_STATUSCODE_GOOD)
+    mbedErr = mbedtls_pk_parse_key(&pc->localPrivateKey, localPrivateKey.data,
+                                   localPrivateKey.length, NULL, 0);
+    if(mbedErr) {
+        retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
         goto error;
+    }
 
     /* Set the local certificate thumbprint */
     retval = UA_ByteString_allocBuffer(&pc->localCertThumbprint, UA_SHA1_LENGTH);

+ 59 - 246
plugins/securityPolicies/ua_securitypolicy_basic256sha256.c

@@ -20,6 +20,7 @@
 #include "ua_types.h"
 #include "ua_plugin_pki.h"
 #include "ua_securitypolicies.h"
+#include "ua_securitypolicy_mbedtls_common.h"
 #include "ua_types_generated_handling.h"
 #include "ua_util.h"
 
@@ -39,24 +40,6 @@
 #define UA_SECURITYPOLICY_BASIC256SHA256_MINASYMKEYLENGTH 256
 #define UA_SECURITYPOLICY_BASIC256SHA256_MAXASYMKEYLENGTH 512
 
-#define UA_LOG_MBEDERR                                                  \
-    char errBuff[300];                                                  \
-    mbedtls_strerror(mbedErr, errBuff, 300);                            \
-    UA_LOG_WARNING(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY, \
-                   "mbedTLS returned an error: %s", errBuff);           \
-
-#define UA_MBEDTLS_ERRORHANDLING(errorcode)                             \
-    if(mbedErr) {                                                       \
-        UA_LOG_MBEDERR                                                  \
-        retval = errorcode;                                             \
-    }
-
-#define UA_MBEDTLS_ERRORHANDLING_RETURN(errorcode)                      \
-    if(mbedErr) {                                                       \
-        UA_LOG_MBEDERR                                                  \
-        return errorcode;                                               \
-    }
-
 typedef struct {
     const UA_SecurityPolicy *securityPolicy;
     UA_ByteString localCertThumbprint;
@@ -112,12 +95,12 @@ asym_verify_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy,
                                                          MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA256,
                                                          UA_SHA256_LENGTH, hash,
                                                          signature->data); */
-
     int mbedErr = mbedtls_pk_verify(&cc->remoteCertificate.pk,
                                     MBEDTLS_MD_SHA256, hash, UA_SHA256_LENGTH,
                                     signature->data, signature->length);
 
-    UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADSECURITYCHECKSFAILED);
+    if(mbedErr)
+        return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
     return UA_STATUSCODE_GOOD;
 }
 
@@ -151,7 +134,8 @@ asym_sign_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy,
                                   UA_SHA256_LENGTH, signature->data,
                                   &sigLen, mbedtls_ctr_drbg_random,
                                   &pc->drbgContext);
-    UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADINTERNALERROR);
+    if(mbedErr)
+        return UA_STATUSCODE_BADINTERNALERROR;
     return UA_STATUSCODE_GOOD;
 }
 
@@ -181,48 +165,14 @@ asym_encrypt_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy,
     if(securityPolicy == NULL || cc == NULL || data == NULL)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    const size_t plainTextBlockSize = securityPolicy->asymmetricModule.cryptoModule.encryptionAlgorithm.
-        getRemotePlainTextBlockSize(securityPolicy, cc);
-
-    if(data->length % plainTextBlockSize != 0)
-        return UA_STATUSCODE_BADINTERNALERROR;
+    const size_t plainTextBlockSize = securityPolicy->asymmetricModule.cryptoModule.
+        encryptionAlgorithm.getRemotePlainTextBlockSize(securityPolicy, cc);
 
     mbedtls_rsa_context *remoteRsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
     mbedtls_rsa_set_padding(remoteRsaContext, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA1);
 
-    UA_ByteString encrypted;
-    const size_t bufferOverhead =
-        UA_SecurityPolicy_getRemoteAsymEncryptionBufferLengthOverhead(securityPolicy, cc, data->length);
-    UA_StatusCode retval = UA_ByteString_allocBuffer(&encrypted, data->length + bufferOverhead);
-    if(retval != UA_STATUSCODE_GOOD)
-        return retval;
-
-    size_t lenDataToEncrypt = data->length;
-    size_t inOffset = 0;
-    size_t offset = 0;
-    const unsigned char *label = NULL;
-    Basic256Sha256_PolicyContext *pc = cc->policyContext;
-    while(lenDataToEncrypt >= plainTextBlockSize) {
-        int mbedErr = mbedtls_rsa_rsaes_oaep_encrypt(remoteRsaContext, mbedtls_ctr_drbg_random,
-                                                     &pc->drbgContext, MBEDTLS_RSA_PUBLIC,
-                                                     label, 0, plainTextBlockSize,
-                                                     data->data + inOffset, encrypted.data + offset);
-
-        UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADINTERNALERROR);
-        if(retval != UA_STATUSCODE_GOOD) {
-            UA_ByteString_deleteMembers(&encrypted);
-            return retval;
-        }
-
-        inOffset += plainTextBlockSize;
-        offset += remoteRsaContext->len;
-        lenDataToEncrypt -= plainTextBlockSize;
-    }
-
-    memcpy(data->data, encrypted.data, offset);
-    UA_ByteString_deleteMembers(&encrypted);
-
-    return UA_STATUSCODE_GOOD;
+    return mbedtls_encrypt_rsaOaep(remoteRsaContext, &cc->policyContext->drbgContext,
+                                   data, plainTextBlockSize);
 }
 
 /* AsymmetricEncryptionAlgorithm_RSA-OAEP-SHA1 */
@@ -232,52 +182,8 @@ asym_decrypt_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy,
                                UA_ByteString *data) {
     if(securityPolicy == NULL || cc == NULL || data == NULL)
         return UA_STATUSCODE_BADINTERNALERROR;
-
-    mbedtls_rsa_context *rsaContext =
-        mbedtls_pk_rsa(cc->policyContext->localPrivateKey);
-
-    mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA1);
-
-    if(data->length % rsaContext->len != 0)
-        return UA_STATUSCODE_BADINTERNALERROR;
-
-    UA_ByteString decrypted;
-    UA_StatusCode retval = UA_ByteString_allocBuffer(&decrypted, data->length);
-    if(retval != UA_STATUSCODE_GOOD)
-        return retval;
-
-    size_t lenDataToDecrypt = data->length;
-    size_t inOffset = 0;
-    size_t offset = 0;
-    size_t outLength = 0;
-    const unsigned char *label = NULL;
-    Basic256Sha256_PolicyContext *pc = cc->policyContext;
-
-    while(lenDataToDecrypt >= rsaContext->len) {
-        int mbedErr = mbedtls_rsa_rsaes_oaep_decrypt(rsaContext, mbedtls_ctr_drbg_random,
-                                                     &pc->drbgContext, MBEDTLS_RSA_PRIVATE,
-                                                     label, 0, &outLength,
-                                                     data->data + inOffset,
-                                                     decrypted.data + offset,
-                                                     decrypted.length - offset);
-        if(mbedErr)
-            UA_ByteString_deleteMembers(&decrypted); // TODO: Maybe change error macro to jump to cleanup?
-        UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADSECURITYCHECKSFAILED);
-
-        inOffset += rsaContext->len;
-        offset += outLength;
-        lenDataToDecrypt -= rsaContext->len;
-    }
-
-    if(lenDataToDecrypt == 0) {
-        memcpy(data->data, decrypted.data, offset);
-        data->length = offset;
-    } else {
-        retval = UA_STATUSCODE_BADINTERNALERROR;
-    }
-
-    UA_ByteString_deleteMembers(&decrypted);
-    return retval;
+    return mbedtls_decrypt_rsaOaep(&cc->policyContext->localPrivateKey,
+                                   &cc->policyContext->drbgContext, data);
 }
 
 static size_t
@@ -306,20 +212,7 @@ asym_makeThumbprint_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy,
                                       UA_ByteString *thumbprint) {
     if(securityPolicy == NULL || certificate == NULL || thumbprint == NULL)
         return UA_STATUSCODE_BADINTERNALERROR;
-
-    if(UA_ByteString_equal(certificate, &UA_BYTESTRING_NULL))
-        return UA_STATUSCODE_BADINTERNALERROR;
-
-    if(thumbprint->length != UA_SHA1_LENGTH)
-        return UA_STATUSCODE_BADINTERNALERROR;
-
-    /* The certificate thumbprint is always a 20 bit sha1 hash, see Part 4 of the Specification. */
-#if MBEDTLS_VERSION_NUMBER >= 0x02070000
-    mbedtls_sha1_ret(certificate->data, certificate->length, thumbprint->data);
-#else
-    mbedtls_sha1(certificate->data, certificate->length, thumbprint->data);
-#endif
-    return UA_STATUSCODE_GOOD;
+    return mbedtls_thumbprint_sha1(certificate, thumbprint);
 }
 
 static UA_StatusCode
@@ -339,14 +232,6 @@ asymmetricModule_compareCertificateThumbprint_sp_basic256sha256(const UA_Securit
 /* SymmetricModule */
 /*******************/
 
-static void
-md_hmac_Basic256Sha256(mbedtls_md_context_t *context, const UA_ByteString *key,
-                       const UA_ByteString *in, unsigned char out[32]) {
-    mbedtls_md_hmac_starts(context, key->data, key->length);
-    mbedtls_md_hmac_update(context, in->data, in->length);
-    mbedtls_md_hmac_finish(context, out);
-}
-
 static UA_StatusCode
 sym_verify_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy,
                              Basic256Sha256_ChannelContext *cc,
@@ -366,7 +251,7 @@ sym_verify_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy,
         (Basic256Sha256_PolicyContext *)securityPolicy->policyContext;
     
     unsigned char mac[UA_SHA256_LENGTH];
-    md_hmac_Basic256Sha256(&pc->sha256MdContext, &cc->remoteSymSigningKey, message, mac);
+    mbedtls_hmac(&pc->sha256MdContext, &cc->remoteSymSigningKey, message, mac);
 
     /* Compare with Signature */
     if(!UA_constantTimeEqual(signature->data, mac, UA_SHA256_LENGTH))
@@ -382,8 +267,8 @@ sym_sign_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy,
     if(signature->length != UA_SHA256_LENGTH)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    md_hmac_Basic256Sha256(&cc->policyContext->sha256MdContext, &cc->localSymSigningKey,
-                           message, signature->data);
+    mbedtls_hmac(&cc->policyContext->sha256MdContext, &cc->localSymSigningKey,
+                 message, signature->data);
     return UA_STATUSCODE_GOOD;
 }
 
@@ -424,17 +309,17 @@ sym_encrypt_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy,
     if(securityPolicy == NULL || cc == NULL || data == NULL)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    if(cc->localSymIv.length !=
-       securityPolicy->symmetricModule.cryptoModule.encryptionAlgorithm.getLocalBlockSize(securityPolicy, cc))
+    if(cc->localSymIv.length != securityPolicy->symmetricModule.cryptoModule.
+       encryptionAlgorithm.getLocalBlockSize(securityPolicy, cc))
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    size_t plainTextBlockSize =
-        securityPolicy->symmetricModule.cryptoModule.encryptionAlgorithm.getLocalPlainTextBlockSize(securityPolicy, cc);
+    size_t plainTextBlockSize = securityPolicy->symmetricModule.cryptoModule.
+        encryptionAlgorithm.getLocalPlainTextBlockSize(securityPolicy, cc);
 
     if(data->length % plainTextBlockSize != 0) {
         UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY,
                      "Length of data to encrypt is not a multiple of the plain text block size."
-                         "Padding might not have been calculated appropriately.");
+                     "Padding might not have been calculated appropriately.");
         return UA_STATUSCODE_BADINTERNALERROR;
     }
 
@@ -442,7 +327,8 @@ sym_encrypt_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy,
     unsigned int keylength = (unsigned int)(cc->localSymEncryptingKey.length * 8);
     mbedtls_aes_context aesContext;
     int mbedErr = mbedtls_aes_setkey_enc(&aesContext, cc->localSymEncryptingKey.data, keylength);
-    UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADINTERNALERROR);
+    if(mbedErr)
+        return UA_STATUSCODE_BADINTERNALERROR;
 
     UA_ByteString ivCopy;
     UA_StatusCode retval = UA_ByteString_copy(&cc->localSymIv, &ivCopy);
@@ -451,7 +337,8 @@ sym_encrypt_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy,
 
     mbedErr = mbedtls_aes_crypt_cbc(&aesContext, MBEDTLS_AES_ENCRYPT, data->length,
                                     ivCopy.data, data->data, data->data);
-    UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADINTERNALERROR);
+    if(mbedErr)
+        retval = UA_STATUSCODE_BADINTERNALERROR;
     UA_ByteString_deleteMembers(&ivCopy);
     return retval;
 }
@@ -463,8 +350,8 @@ sym_decrypt_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy,
     if(securityPolicy == NULL || cc == NULL || data == NULL)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    size_t encryptionBlockSize =
-        securityPolicy->symmetricModule.cryptoModule.encryptionAlgorithm.getRemoteBlockSize(securityPolicy, cc);
+    size_t encryptionBlockSize = securityPolicy->symmetricModule.cryptoModule.
+        encryptionAlgorithm.getRemoteBlockSize(securityPolicy, cc);
 
     if(cc->remoteSymIv.length != encryptionBlockSize)
         return UA_STATUSCODE_BADINTERNALERROR;
@@ -478,7 +365,8 @@ sym_decrypt_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy,
     unsigned int keylength = (unsigned int)(cc->remoteSymEncryptingKey.length * 8);
     mbedtls_aes_context aesContext;
     int mbedErr = mbedtls_aes_setkey_dec(&aesContext, cc->remoteSymEncryptingKey.data, keylength);
-    UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADINTERNALERROR);
+    if(mbedErr)
+        return UA_STATUSCODE_BADINTERNALERROR;
 
     UA_ByteString ivCopy;
     UA_StatusCode retval = UA_ByteString_copy(&cc->remoteSymIv, &ivCopy);
@@ -487,18 +375,12 @@ sym_decrypt_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy,
 
     mbedErr = mbedtls_aes_crypt_cbc(&aesContext, MBEDTLS_AES_DECRYPT, data->length,
                                     ivCopy.data, data->data, data->data);
-    UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADINTERNALERROR);
+    if(mbedErr)
+        retval = UA_STATUSCODE_BADINTERNALERROR;
     UA_ByteString_deleteMembers(&ivCopy);
     return retval;
 }
 
-static void
-swapBuffers_Basic256Sha256(UA_ByteString *const bufA, UA_ByteString *const bufB) {
-    UA_ByteString tmp = *bufA;
-    *bufA = *bufB;
-    *bufB = tmp;
-}
-
 static UA_StatusCode
 sym_generateKey_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy,
                                   const UA_ByteString *secret, const UA_ByteString *seed,
@@ -509,73 +391,7 @@ sym_generateKey_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy,
     Basic256Sha256_PolicyContext *pc =
         (Basic256Sha256_PolicyContext *)securityPolicy->policyContext;
 
-    size_t hashLen = 0;
-    const mbedtls_md_info_t *mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
-    hashLen = (size_t)mbedtls_md_get_size(mdInfo);
-
-    UA_ByteString A_and_seed;
-    UA_ByteString_allocBuffer(&A_and_seed, hashLen + seed->length);
-    memcpy(A_and_seed.data + hashLen, seed->data, seed->length);
-
-    UA_ByteString ANext_and_seed;
-    UA_ByteString_allocBuffer(&ANext_and_seed, hashLen + seed->length);
-    memcpy(ANext_and_seed.data + hashLen, seed->data, seed->length);
-
-    UA_ByteString A = {
-        hashLen,
-        A_and_seed.data
-    };
-
-    UA_ByteString ANext = {
-        hashLen,
-        ANext_and_seed.data
-    };
-
-    md_hmac_Basic256Sha256(&pc->sha256MdContext, secret, seed, A.data);
-
-    UA_StatusCode retval = 0;
-    for(size_t offset = 0; offset < out->length; offset += hashLen) {
-        UA_ByteString outSegment = {
-            hashLen,
-            out->data + offset
-        };
-        UA_Boolean bufferAllocated = UA_FALSE;
-        // Not enough room in out buffer to write the hash.
-        if(offset + hashLen > out->length) {
-            outSegment.data = NULL;
-            outSegment.length = 0;
-            retval = UA_ByteString_allocBuffer(&outSegment, hashLen);
-            if(retval != UA_STATUSCODE_GOOD) {
-                UA_ByteString_deleteMembers(&A_and_seed);
-                UA_ByteString_deleteMembers(&ANext_and_seed);
-                return retval;
-            }
-            bufferAllocated = UA_TRUE;
-        }
-
-        md_hmac_Basic256Sha256(&pc->sha256MdContext, secret, &A_and_seed, outSegment.data);
-        md_hmac_Basic256Sha256(&pc->sha256MdContext, secret, &A, ANext.data);
-
-        if(retval != UA_STATUSCODE_GOOD) {
-            if(bufferAllocated)
-                UA_ByteString_deleteMembers(&outSegment);
-            UA_ByteString_deleteMembers(&A_and_seed);
-            UA_ByteString_deleteMembers(&ANext_and_seed);
-            return retval;
-        }
-
-        if(bufferAllocated) {
-            memcpy(out->data + offset, outSegment.data, out->length - offset);
-            UA_ByteString_deleteMembers(&outSegment);
-        }
-
-        swapBuffers_Basic256Sha256(&ANext_and_seed, &A_and_seed);
-        swapBuffers_Basic256Sha256(&ANext, &A);
-    }
-
-    UA_ByteString_deleteMembers(&A_and_seed);
-    UA_ByteString_deleteMembers(&ANext_and_seed);
-    return UA_STATUSCODE_GOOD;
+    return mbedtls_generateKey(&pc->sha256MdContext, secret, seed, out);
 }
 
 static UA_StatusCode
@@ -584,12 +400,11 @@ sym_generateNonce_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy,
     if(securityPolicy == NULL || securityPolicy->policyContext == NULL || out == NULL)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    Basic256Sha256_PolicyContext *data =
+    Basic256Sha256_PolicyContext *pc =
         (Basic256Sha256_PolicyContext *)securityPolicy->policyContext;
-
-    int mbedErr = mbedtls_ctr_drbg_random(&data->drbgContext, out->data, out->length);
-    UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADUNEXPECTEDERROR);
-
+    int mbedErr = mbedtls_ctr_drbg_random(&pc->drbgContext, out->data, out->length);
+    if(mbedErr)
+        return UA_STATUSCODE_BADUNEXPECTEDERROR;
     return UA_STATUSCODE_GOOD;
 }
 
@@ -604,12 +419,11 @@ parseRemoteCertificate_sp_basic256sha256(Basic256Sha256_ChannelContext *cc,
     if(remoteCertificate == NULL || cc == NULL)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    const UA_SecurityPolicy *securityPolicy = cc->policyContext->securityPolicy;
-
     /* Parse the certificate */
     int mbedErr = mbedtls_x509_crt_parse(&cc->remoteCertificate, remoteCertificate->data,
                                          remoteCertificate->length);
-    UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADSECURITYCHECKSFAILED);
+    if(mbedErr)
+        return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
 
     /* Check the key length */
     mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
@@ -738,15 +552,11 @@ channelContext_compareCertificate_sp_basic256sha256(const Basic256Sha256_Channel
     if(cc == NULL || certificate == NULL)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    const UA_SecurityPolicy *securityPolicy = cc->policyContext->securityPolicy;
-
     mbedtls_x509_crt cert;
     mbedtls_x509_crt_init(&cert);
     int mbedErr = mbedtls_x509_crt_parse(&cert, certificate->data, certificate->length);
-    if(mbedErr) {
-        UA_LOG_MBEDERR;
+    if(mbedErr)
         return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
-    }
 
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
     if(cert.raw.len != cc->remoteCertificate.raw.len ||
@@ -799,8 +609,8 @@ updateCertificateAndPrivateKey_sp_basic256sha256(UA_SecurityPolicy *securityPoli
 
     UA_ByteString_deleteMembers(&securityPolicy->localCertificate);
 
-    UA_StatusCode retval =
-            UA_ByteString_allocBuffer(&securityPolicy->localCertificate, newCertificate.length + 1);
+    UA_StatusCode retval = UA_ByteString_allocBuffer(&securityPolicy->localCertificate,
+                                                     newCertificate.length + 1);
     if(retval != UA_STATUSCODE_GOOD)
         return retval;
     memcpy(securityPolicy->localCertificate.data, newCertificate.data, newCertificate.length);
@@ -810,12 +620,12 @@ updateCertificateAndPrivateKey_sp_basic256sha256(UA_SecurityPolicy *securityPoli
     /* Set the new private key */
     mbedtls_pk_free(&pc->localPrivateKey);
     mbedtls_pk_init(&pc->localPrivateKey);
-    int mbedErr = mbedtls_pk_parse_key(&pc->localPrivateKey,
-                                       newPrivateKey.data, newPrivateKey.length,
-                                       NULL, 0);
-    UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADSECURITYCHECKSFAILED);
-    if(retval != UA_STATUSCODE_GOOD)
+    int mbedErr = mbedtls_pk_parse_key(&pc->localPrivateKey, newPrivateKey.data,
+                                       newPrivateKey.length, NULL, 0);
+    if(mbedErr) {
+        retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
         goto error;
+    }
 
     retval = asym_makeThumbprint_sp_basic256sha256(pc->securityPolicy,
                                                    &securityPolicy->localCertificate,
@@ -859,34 +669,37 @@ policyContext_newContext_sp_basic256sha256(UA_SecurityPolicy *securityPolicy,
     /* Initialized the message digest */
     const mbedtls_md_info_t *const mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
     int mbedErr = mbedtls_md_setup(&pc->sha256MdContext, mdInfo, MBEDTLS_MD_SHA256);
-    UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADOUTOFMEMORY);
-    if(retval != UA_STATUSCODE_GOOD)
+    if(mbedErr) {
+        retval = UA_STATUSCODE_BADOUTOFMEMORY;
         goto error;
+    }
 
     /* Add the system entropy source */
     mbedErr = mbedtls_entropy_add_source(&pc->entropyContext,
                                          mbedtls_platform_entropy_poll, NULL, 0,
                                          MBEDTLS_ENTROPY_SOURCE_STRONG);
-    UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADSECURITYCHECKSFAILED);
-    if(retval != UA_STATUSCODE_GOOD)
+    if(mbedErr) {
+        retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
         goto error;
+    }
 
     /* Seed the RNG */
     char *personalization = "open62541-drbg";
     mbedErr = mbedtls_ctr_drbg_seed(&pc->drbgContext, mbedtls_entropy_func,
                                     &pc->entropyContext,
                                     (const unsigned char *)personalization, 14);
-    UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADSECURITYCHECKSFAILED);
-    if(retval != UA_STATUSCODE_GOOD)
+    if(mbedErr) {
+        retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
         goto error;
+    }
 
     /* Set the private key */
-    mbedErr = mbedtls_pk_parse_key(&pc->localPrivateKey,
-                                   localPrivateKey.data, localPrivateKey.length,
-                                   NULL, 0);
-    UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADSECURITYCHECKSFAILED);
-    if(retval != UA_STATUSCODE_GOOD)
+    mbedErr = mbedtls_pk_parse_key(&pc->localPrivateKey, localPrivateKey.data,
+                                   localPrivateKey.length, NULL, 0);
+    if(mbedErr) {
+        retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
         goto error;
+    }
 
     /* Set the local certificate thumbprint */
     retval = UA_ByteString_allocBuffer(&pc->localCertThumbprint, UA_SHA1_LENGTH);

+ 239 - 0
plugins/securityPolicies/ua_securitypolicy_mbedtls_common.c

@@ -0,0 +1,239 @@
+#include <mbedtls/aes.h>
+#include <mbedtls/md.h>
+#include <mbedtls/x509_crt.h>
+#include <mbedtls/ctr_drbg.h>
+#include <mbedtls/entropy.h>
+#include <mbedtls/entropy_poll.h>
+#include <mbedtls/error.h>
+#include <mbedtls/version.h>
+#include <mbedtls/sha1.h>
+
+#include "ua_types.h"
+#include "ua_plugin_pki.h"
+#include "ua_securitypolicies.h"
+#include "ua_securitypolicy_mbedtls_common.h"
+
+void
+swapBuffers(UA_ByteString *const bufA, UA_ByteString *const bufB) {
+    UA_ByteString tmp = *bufA;
+    *bufA = *bufB;
+    *bufB = tmp;
+}
+
+void
+mbedtls_hmac(mbedtls_md_context_t *context, const UA_ByteString *key,
+             const UA_ByteString *in, unsigned char *out) {
+    mbedtls_md_hmac_starts(context, key->data, key->length);
+    mbedtls_md_hmac_update(context, in->data, in->length);
+    mbedtls_md_hmac_finish(context, out);
+}
+
+UA_StatusCode
+mbedtls_generateKey(mbedtls_md_context_t *context,
+                    const UA_ByteString *secret, const UA_ByteString *seed,
+                    UA_ByteString *out) {
+    size_t hashLen = (size_t)mbedtls_md_get_size(context->md_info);
+
+    UA_ByteString A_and_seed;
+    UA_ByteString_allocBuffer(&A_and_seed, hashLen + seed->length);
+    memcpy(A_and_seed.data + hashLen, seed->data, seed->length);
+
+    UA_ByteString ANext_and_seed;
+    UA_ByteString_allocBuffer(&ANext_and_seed, hashLen + seed->length);
+    memcpy(ANext_and_seed.data + hashLen, seed->data, seed->length);
+
+    UA_ByteString A = {
+        hashLen,
+        A_and_seed.data
+    };
+
+    UA_ByteString ANext = {
+        hashLen,
+        ANext_and_seed.data
+    };
+
+    mbedtls_hmac(context, secret, seed, A.data);
+
+    UA_StatusCode retval = 0;
+    for(size_t offset = 0; offset < out->length; offset += hashLen) {
+        UA_ByteString outSegment = {
+            hashLen,
+            out->data + offset
+        };
+        UA_Boolean bufferAllocated = UA_FALSE;
+        // Not enough room in out buffer to write the hash.
+        if(offset + hashLen > out->length) {
+            outSegment.data = NULL;
+            outSegment.length = 0;
+            retval = UA_ByteString_allocBuffer(&outSegment, hashLen);
+            if(retval != UA_STATUSCODE_GOOD) {
+                UA_ByteString_deleteMembers(&A_and_seed);
+                UA_ByteString_deleteMembers(&ANext_and_seed);
+                return retval;
+            }
+            bufferAllocated = UA_TRUE;
+        }
+
+        mbedtls_hmac(context, secret, &A_and_seed, outSegment.data);
+        mbedtls_hmac(context, secret, &A, ANext.data);
+
+        if(retval != UA_STATUSCODE_GOOD) {
+            if(bufferAllocated)
+                UA_ByteString_deleteMembers(&outSegment);
+            UA_ByteString_deleteMembers(&A_and_seed);
+            UA_ByteString_deleteMembers(&ANext_and_seed);
+            return retval;
+        }
+
+        if(bufferAllocated) {
+            memcpy(out->data + offset, outSegment.data, out->length - offset);
+            UA_ByteString_deleteMembers(&outSegment);
+        }
+
+        swapBuffers(&ANext_and_seed, &A_and_seed);
+        swapBuffers(&ANext, &A);
+    }
+
+    UA_ByteString_deleteMembers(&A_and_seed);
+    UA_ByteString_deleteMembers(&ANext_and_seed);
+    return UA_STATUSCODE_GOOD;
+}
+
+UA_StatusCode
+mbedtls_verifySig_sha1(mbedtls_x509_crt *certificate, const UA_ByteString *message,
+                       const UA_ByteString *signature) {
+    /* Compute the sha1 hash */
+    unsigned char hash[UA_SHA1_LENGTH];
+#if MBEDTLS_VERSION_NUMBER >= 0x02070000
+    mbedtls_sha1_ret(message->data, message->length, hash);
+#else
+    mbedtls_sha1(message->data, message->length, hash);
+#endif
+
+    /* Set the RSA settings */
+    mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(certificate->pk);
+    if(!rsaContext)
+        return UA_STATUSCODE_BADINTERNALERROR;
+    mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V15, 0);
+
+    /* Verify */
+    int mbedErr = mbedtls_pk_verify(&certificate->pk,
+                                    MBEDTLS_MD_SHA1, hash, UA_SHA1_LENGTH,
+                                    signature->data, signature->length);
+    if(mbedErr)
+        return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
+    return UA_STATUSCODE_GOOD;
+}
+
+UA_StatusCode
+mbedtls_sign_sha1(mbedtls_pk_context *localPrivateKey,
+                  mbedtls_ctr_drbg_context *drbgContext,
+                  const UA_ByteString *message,
+                  UA_ByteString *signature) {
+    unsigned char hash[UA_SHA1_LENGTH];
+#if MBEDTLS_VERSION_NUMBER >= 0x02070000
+    mbedtls_sha1_ret(message->data, message->length, hash);
+#else
+    mbedtls_sha1(message->data, message->length, hash);
+#endif
+
+    mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(*localPrivateKey);
+    mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V15, 0);
+
+    size_t sigLen = 0;
+    int mbedErr = mbedtls_pk_sign(localPrivateKey, MBEDTLS_MD_SHA1, hash,
+                                  UA_SHA1_LENGTH, signature->data, &sigLen,
+                                  mbedtls_ctr_drbg_random, drbgContext);
+    if(mbedErr)
+        return UA_STATUSCODE_BADINTERNALERROR;
+    return UA_STATUSCODE_GOOD;
+}
+
+UA_StatusCode
+mbedtls_thumbprint_sha1(const UA_ByteString *certificate,
+                        UA_ByteString *thumbprint) {
+    if(UA_ByteString_equal(certificate, &UA_BYTESTRING_NULL))
+        return UA_STATUSCODE_BADINTERNALERROR;
+
+    if(thumbprint->length != UA_SHA1_LENGTH)
+        return UA_STATUSCODE_BADINTERNALERROR;
+
+    /* The certificate thumbprint is always a 20 bit sha1 hash, see Part 4 of the Specification. */
+#if MBEDTLS_VERSION_NUMBER >= 0x02070000
+    mbedtls_sha1_ret(certificate->data, certificate->length, thumbprint->data);
+#else
+    mbedtls_sha1(certificate->data, certificate->length, thumbprint->data);
+#endif
+    return UA_STATUSCODE_GOOD;
+}
+
+UA_StatusCode
+mbedtls_encrypt_rsaOaep(mbedtls_rsa_context *context,
+                        mbedtls_ctr_drbg_context *drbgContext,
+                        UA_ByteString *data, const size_t plainTextBlockSize) {
+    if(data->length % plainTextBlockSize != 0)
+        return UA_STATUSCODE_BADINTERNALERROR;
+
+    size_t max_blocks = data->length / plainTextBlockSize;
+
+    UA_ByteString encrypted;
+    UA_StatusCode retval = UA_ByteString_allocBuffer(&encrypted, max_blocks * context->len);
+    if(retval != UA_STATUSCODE_GOOD)
+        return retval;
+
+    size_t lenDataToEncrypt = data->length;
+    size_t inOffset = 0;
+    size_t offset = 0;
+    const unsigned char *label = NULL;
+    while(lenDataToEncrypt >= plainTextBlockSize) {
+        int mbedErr = mbedtls_rsa_rsaes_oaep_encrypt(context, mbedtls_ctr_drbg_random,
+                                                     drbgContext, MBEDTLS_RSA_PUBLIC,
+                                                     label, 0, plainTextBlockSize,
+                                                     data->data + inOffset, encrypted.data + offset);
+        if(mbedErr) {
+            UA_ByteString_deleteMembers(&encrypted);
+            return UA_STATUSCODE_BADINTERNALERROR;
+        }
+
+        inOffset += plainTextBlockSize;
+        offset += context->len;
+        lenDataToEncrypt -= plainTextBlockSize;
+    }
+
+    memcpy(data->data, encrypted.data, offset);
+    UA_ByteString_deleteMembers(&encrypted);
+    return UA_STATUSCODE_GOOD;
+}
+
+UA_StatusCode
+mbedtls_decrypt_rsaOaep(mbedtls_pk_context *localPrivateKey,
+                        mbedtls_ctr_drbg_context *drbgContext,
+                        UA_ByteString *data) {
+    mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(*localPrivateKey);
+    mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA1);
+
+    if(data->length % rsaContext->len != 0)
+        return UA_STATUSCODE_BADINTERNALERROR;
+
+    size_t inOffset = 0;
+    size_t outOffset = 0;
+    size_t outLength = 0;
+    unsigned char buf[512];
+
+    while(inOffset < data->length) {
+        int mbedErr = mbedtls_rsa_rsaes_oaep_decrypt(rsaContext, mbedtls_ctr_drbg_random,
+                                                     drbgContext, MBEDTLS_RSA_PRIVATE,
+                                                     NULL, 0, &outLength,
+                                                     data->data + inOffset,
+                                                     buf, 512);
+        if(mbedErr)
+            return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
+
+        memcpy(data->data + outOffset, buf, outLength);
+        inOffset += rsaContext->len;
+        outOffset += outLength;
+    }
+
+    data->length = outOffset;
+    return UA_STATUSCODE_GOOD;
+}

+ 63 - 0
plugins/securityPolicies/ua_securitypolicy_mbedtls_common.h

@@ -0,0 +1,63 @@
+/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
+ * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. 
+ *
+ *    Copyright 2019 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
+ */
+
+#ifndef UA_SECURITYPOLICY_MBEDTLS_COMMON_H_
+#define UA_SECURITYPOLICY_MBEDTLS_COMMON_H_
+
+#include "ua_plugin_securitypolicy.h"
+#include <mbedtls/md.h>
+#include <mbedtls/x509_crt.h>
+#include <mbedtls/ctr_drbg.h>
+
+#define UA_SHA1_LENGTH 20
+
+_UA_BEGIN_DECLS
+
+#ifdef UA_ENABLE_ENCRYPTION
+
+void
+swapBuffers(UA_ByteString *const bufA, UA_ByteString *const bufB);
+
+void
+mbedtls_hmac(mbedtls_md_context_t *context, const UA_ByteString *key,
+             const UA_ByteString *in, unsigned char *out);
+
+UA_StatusCode
+mbedtls_generateKey(mbedtls_md_context_t *context,
+                    const UA_ByteString *secret, const UA_ByteString *seed,
+                    UA_ByteString *out);
+
+UA_StatusCode
+mbedtls_verifySig_sha1(mbedtls_x509_crt *certificate, const UA_ByteString *message,
+                       const UA_ByteString *signature);
+
+UA_StatusCode
+mbedtls_sign_sha1(mbedtls_pk_context *localPrivateKey,
+                  mbedtls_ctr_drbg_context *drbgContext,
+                  const UA_ByteString *message,
+                  UA_ByteString *signature);
+
+UA_StatusCode
+mbedtls_thumbprint_sha1(const UA_ByteString *certificate,
+                        UA_ByteString *thumbprint);
+
+/* Set the hashing scheme before calling
+ * E.g. mbedtls_rsa_set_padding(context, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA1); */
+UA_StatusCode
+mbedtls_encrypt_rsaOaep(mbedtls_rsa_context *context,
+                        mbedtls_ctr_drbg_context *drbgContext,
+                        UA_ByteString *data, const size_t plainTextBlockSize);
+
+UA_StatusCode
+mbedtls_decrypt_rsaOaep(mbedtls_pk_context *localPrivateKey,
+                        mbedtls_ctr_drbg_context *drbgContext,
+                        UA_ByteString *data);
+
+#endif
+
+_UA_END_DECLS
+
+#endif /* UA_SECURITYPOLICY_MBEDTLS_COMMON_H_ */

+ 5 - 4
tests/fuzz/CMakeLists.txt

@@ -63,10 +63,11 @@ set(fuzzing_plugin_sources ${PROJECT_SOURCE_DIR}/arch/ua_network_tcp.c
 )
 
 if(UA_ENABLE_ENCRYPTION)
-    set(fuzzing_plugin_sources ${fuzzing_plugin_sources}
-        ${PROJECT_SOURCE_DIR}/plugins/securityPolicies/ua_securitypolicy_basic128rsa15.c)
-    set(fuzzing_plugin_sources ${fuzzing_plugin_sources}
-        ${PROJECT_SOURCE_DIR}/plugins/securityPolicies/ua_securitypolicy_basic256sha256.c)
+  list(APPEND fuzzing_plugin_sources
+              ${PROJECT_SOURCE_DIR}/plugins/securityPolicies/ua_securitypolicy_mbedtls_common.c
+              ${PROJECT_SOURCE_DIR}/plugins/securityPolicies/ua_securitypolicy_basic128rsa15.c
+              ${PROJECT_SOURCE_DIR}/plugins/securityPolicies/ua_securitypolicy_basic256.c
+              ${PROJECT_SOURCE_DIR}/plugins/securityPolicies/ua_securitypolicy_basic256sha256.c)
 endif()
 
 add_library(open62541-fuzzplugins OBJECT