Skip to content

Commit daa7bfc

Browse files
committed
stdlib: add a secret key for hashing
1 parent 532cf06 commit daa7bfc

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

stdlib/public/SwiftShims/GlobalObjects.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ struct _SwiftEmptyArrayStorage {
3939
extern SWIFT_RUNTIME_STDLIB_INTERFACE
4040
struct _SwiftEmptyArrayStorage _swiftEmptyArrayStorage;
4141

42+
struct _SwiftHashingSecretKey {
43+
__swift_uint64_t key0;
44+
__swift_uint64_t key1;
45+
};
46+
47+
extern SWIFT_RUNTIME_STDLIB_INTERFACE
48+
struct _SwiftHashingSecretKey _swift_stdlib_Hashing_secretKey;
49+
4250
extern SWIFT_RUNTIME_STDLIB_INTERFACE
4351
__swift_uint64_t _swift_stdlib_HashingDetail_fixedSeedOverride;
4452

stdlib/public/core/Hashing.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,27 @@
2323

2424
import SwiftShims
2525

26+
public // @testable
27+
struct _Hashing {
28+
// FIXME(ABI): make this an actual public API.
29+
public // SPI
30+
static var secretKey: (UInt64, UInt64) {
31+
get {
32+
// The variable itself is defined in C++ code so that it is initialized
33+
// during static construction. Almost every Swift program uses hash
34+
// tables, so initializing the secret key during the startup seems to be
35+
// the right trade-off.
36+
return (
37+
_swift_stdlib_Hashing_secretKey.key0,
38+
_swift_stdlib_Hashing_secretKey.key1)
39+
}
40+
set {
41+
(_swift_stdlib_Hashing_secretKey.key0,
42+
_swift_stdlib_Hashing_secretKey.key1) = newValue
43+
}
44+
}
45+
}
46+
2647
public // @testable
2748
struct _HashingDetail {
2849

stdlib/public/stubs/GlobalObjects.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
#include "../SwiftShims/GlobalObjects.h"
2020
#include "swift/Runtime/Metadata.h"
21+
#include "swift/Runtime/Debug.h"
22+
#include <stdlib.h>
2123

2224
namespace swift {
2325
// FIXME(ABI): does this declaration need SWIFT_RUNTIME_STDLIB_INTERFACE?
@@ -39,6 +41,32 @@ swift::_SwiftEmptyArrayStorage swift::_swiftEmptyArrayStorage = {
3941
}
4042
};
4143

44+
static __swift_uint64_t randomUInt64() {
45+
#if defined(__APPLE__)
46+
return static_cast<__swift_uint64_t>(arc4random()) |
47+
(static_cast<__swift_uint64_t>(arc4random()) << 32);
48+
#else
49+
auto devUrandom = fopen("/dev/urandom", "r");
50+
if (!devUrandom) {
51+
swift::fatalError(/* flags = */ 0, "Opening \"/dev/urandom\" failed");
52+
}
53+
uint64_t result;
54+
if (fread(&result, sizeof(result), 1, devUrandom) != 1) {
55+
swift::fatalError(/* flags = */ 0, "Reading from \"/dev/urandom\" failed");
56+
}
57+
if (fclose(devUrandom)) {
58+
swift::fatalError(/* flags = */ 0, "Closing \"/dev/urandom\" failed");
59+
}
60+
return result;
61+
#endif
62+
}
63+
64+
SWIFT_ALLOWED_RUNTIME_GLOBAL_CTOR_BEGIN
65+
swift::_SwiftHashingSecretKey swift::_swift_stdlib_Hashing_secretKey = {
66+
randomUInt64(), randomUInt64()
67+
};
68+
SWIFT_ALLOWED_RUNTIME_GLOBAL_CTOR_END
69+
4270
__swift_uint64_t swift::_swift_stdlib_HashingDetail_fixedSeedOverride = 0;
4371

4472
namespace llvm { namespace hashing { namespace detail {

0 commit comments

Comments
 (0)