Procházet zdrojové kódy

Use constant time memcmp to verify signatures to mitigate timing attacks

Patrick Gansterer před 5 roky
rodič
revize
3866e0c07a

+ 19 - 0
include/ua_util.h

@@ -108,6 +108,25 @@ UA_ByteString_toBase64String(const UA_ByteString *byteString, UA_String *str);
 UA_StatusCode UA_EXPORT
 UA_NodeId_toString(const UA_NodeId *nodeId, UA_String *nodeIdStr);
 
+/*
+ * Compare memory in constant time to mitigate timing attacks.
+ *
+ * @return true if ptr1 and ptr2 are equal for length bytes.
+ */
+static UA_INLINE UA_Boolean
+UA_constantTimeEqual(const void *ptr1, const void *ptr2, size_t length) {
+    volatile const UA_Byte *a = (volatile const UA_Byte *)ptr1;
+    volatile const UA_Byte *b = (volatile const UA_Byte *)ptr2;
+    volatile UA_Byte c = 0;
+
+    for(size_t i = 0; i < length; ++i) {
+        UA_Byte x = a[i], y = b[i];
+        c |= x ^ y;
+    }
+
+    return !c;
+}
+
 _UA_END_DECLS
 
 #endif /* UA_HELPER_H_ */

+ 2 - 1
plugins/securityPolicies/ua_securitypolicy_basic128rsa15.c

@@ -19,6 +19,7 @@
 #include "ua_plugin_pki.h"
 #include "ua_securitypolicies.h"
 #include "ua_types_generated_handling.h"
+#include "ua_util.h"
 
 /* Notes:
  * mbedTLS' AES allows in-place encryption and decryption. Sow we don't have to
@@ -346,7 +347,7 @@ sym_verify_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy,
     md_hmac(&pc->sha1MdContext, &cc->remoteSymSigningKey, message, mac);
 
     /* Compare with Signature */
-    if(memcmp(signature->data, mac, UA_SHA1_LENGTH) != 0)
+    if(!UA_constantTimeEqual(signature->data, mac, UA_SHA1_LENGTH))
         return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
     return UA_STATUSCODE_GOOD;
 }

+ 2 - 1
plugins/securityPolicies/ua_securitypolicy_basic256sha256.c

@@ -21,6 +21,7 @@
 #include "ua_plugin_pki.h"
 #include "ua_securitypolicies.h"
 #include "ua_types_generated_handling.h"
+#include "ua_util.h"
 
 /* Notes:
  * mbedTLS' AES allows in-place encryption and decryption. Sow we don't have to
@@ -368,7 +369,7 @@ sym_verify_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy,
     md_hmac_Basic256Sha256(&pc->sha256MdContext, &cc->remoteSymSigningKey, message, mac);
 
     /* Compare with Signature */
-    if(memcmp(signature->data, mac, UA_SHA256_LENGTH) != 0)
+    if(!UA_constantTimeEqual(signature->data, mac, UA_SHA256_LENGTH))
         return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
     return UA_STATUSCODE_GOOD;
 }