Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/daily_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,11 @@ jobs:
uses: ./.github/workflows/library_interop_tests.yml
with:
dafny: ${{needs.getVersion.outputs.version}}
daily-fuzz-interop-test:
needs: getVersion
if: github.event_name != 'schedule' || github.repository_owner == 'aws'
uses: ./.github/workflows/library_interop_tests.yml
with:
dafny: ${{needs.getVersion.outputs.version}}
fuzz-testing: true
num-fuzz-vectors: 10000
19 changes: 17 additions & 2 deletions .github/workflows/library_interop_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ on:
required: false
default: false
type: boolean
num-fuzz-vectors:
description: "Number of fuzz test vectors to generate (only used when fuzz-testing is true)"
required: false
default: 2000
type: number

jobs:
generateEncryptVectors:
Expand All @@ -37,6 +42,11 @@ jobs:
permissions:
id-token: write
contents: read
env:
# Increase Rust stack size for large-scale fuzz testing with 10,000+ test vectors
RUST_MIN_STACK: 404857600
# Increase Go stack size for large-scale fuzz testing with 10,000+ test vectors
GOSTACKSIZE: 16m
steps:
- name: Support longpaths on Git checkout
run: |
Expand Down Expand Up @@ -200,8 +210,8 @@ jobs:
working-directory: ./${{ matrix.library }}
run: |
if [ "${{ inputs.fuzz-testing }}" = "true" ]; then
echo "Generating fuzzed test vectors"
make test_generate_fuzz_vectors_${{ matrix.language }} NUM_VECTORS=2000
echo "Generating fuzzed test vectors (${{ inputs.num-fuzz-vectors }} vectors)"
make test_generate_fuzz_vectors_${{ matrix.language }} NUM_VECTORS=${{ inputs.num-fuzz-vectors }}
else
make test_generate_vectors_${{ matrix.language }}
fi
Expand Down Expand Up @@ -235,6 +245,11 @@ jobs:
permissions:
id-token: write
contents: read
env:
# Increase Rust stack size for large-scale fuzz testing with 10,000+ test vectors
RUST_MIN_STACK: 404857600
# Increase Go stack size for large-scale fuzz testing with 10,000+ test vectors
GOSTACKSIZE: 16m
steps:
- name: Support longpaths on Git checkout
run: |
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/pull.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ jobs:
with:
dafny: ${{needs.getVersion.outputs.version}}
fuzz-testing: true
num-fuzz-vectors: 10000
secrets: inherit
pr-ci-all-required:
if: always()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
"kms": "KMS keyring test with Unicode fuzzing"
}

#TODO-Fuzztesting: #include the other keys: rsa for raw keys. Other test types too
# Key, Algorithm, Test-Type, Key-Material Definitions
KMS_KEYS = ["us-west-2-mrk", "us-east-1-mrk", "us-west-2-decryptable"] #us-west-2-rsa-mrk (already have rsa), us-west-2-256-ecc, us-west-2-384-ecc (and already have enough ecc)
RAW_KEY_TYPES = ["aes-128", "aes-192", "aes-256", "ecc-256", "ecc-384", "ecc-521"] #rsa-4096 not included because of complex interdependencies and structural requirements
Expand Down Expand Up @@ -97,7 +96,7 @@

# Unicode strategies for maximum diversity
unicode_strategies = [
st.text(min_size=1, max_size=50), # Normal text
st.text(min_size=1, max_size=50),
st.text(min_size=1, max_size=50, alphabet=st.characters(categories=['So', 'Sc', 'Sk', 'Sm'])), #Symbols
st.text(min_size=1, max_size=50, alphabet=st.characters(categories=['Lo', 'Ll', 'Lu', 'Lm', 'Lt'])), #Letters
st.text(min_size=1, max_size=50, alphabet=st.characters(categories=['Nd', 'Nl', 'No'])), #Numbers
Expand Down Expand Up @@ -143,7 +142,6 @@ def fuzz_key_identifiers(draw, base_key_id: str) -> Dict[str, Any]:

return {KEY_ID_FIELD: fuzzed_key_id, KEY_NAMESPACE_FIELD: key_namespace, KEY_ID_IN_MATERIAL_FIELD: key_id_in_material}

#TODO-Fuzztesting: Strengthening encryption context fuzzing with specific edge cases (close to the character limitation for encryption context (8,192))
@composite
def fuzz_encryption_context(draw):
"""Generate diverse encryption contexts with Unicode characters.
Expand All @@ -162,7 +160,6 @@ def fuzz_encryption_context(draw):

return context

#TODO-Fuzztesting: "negative-encrypt-keyring" fuzzing functionality: in fuzzToDos branch, implemented tests with missing required keys (for KMS keyrings) or invalid key material (raw keryings), but it could also fail because of algo mismatches or invalid encryption context formats
def generate_required_keys(draw, encryption_context: Dict[str, str]) -> List[str]:
"""Generate requiredEncryptionContextKeys from existing context keys."""
context_keys = list(encryption_context.keys())
Expand All @@ -178,7 +175,6 @@ def create_key_description(draw, keyring_type: str, kms_key: str, required_keys:
else:
raise ValueError(f"Unknown keyring type: {keyring_type}")

#TODO-Fuzztesting: for both raw and kms keys, different keys have different description structures; this has to be taken into consideration for the remaining keys
def create_raw_key_description(draw) -> Dict[str, Any]:
"""Create raw keyring description."""
raw_key_id = draw(st.sampled_from(RAW_KEY_TYPES))
Expand Down Expand Up @@ -325,7 +321,6 @@ def generate_fuzz_test_vectors(num_vectors) -> Tuple[Dict[str, Any], Dict[str, A
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=NonInteractiveExampleWarning)
for i in range(num_vectors):
# TODO-Fuzztesting: remove .example() usage. Context: we're using Hypothesis as a data generator, not for testing properties.
# Hypothesis is designed for property-based testing, so when using .example() it informs us that we should be using @given to actually test properties, not just generate examples.
# But we're in a different use case, because we're essentially using Hypothesis as a sophisticated random data generator to create test vectors that will be evaluated by a different test system
# Warning surpressed so that it doesn't fill the output with this message: https://github.com/aws/aws-cryptographic-material-providers-library/pull/1630/files#r2226909207; it will paste that message 2000 times for 2000 test vectors, for e.g.
Expand All @@ -336,8 +331,6 @@ def generate_fuzz_test_vectors(num_vectors) -> Tuple[Dict[str, Any], Dict[str, A
new_keys = extract_new_keys(test_vectors)
return test_vectors, new_keys

#TODO-Fuzztesting: increase the number of test vectors (for CI), need to increase the stack perhaps?
#TODO-Fuzztesting: Add a logging mechanism to log errors/vulnerabilities we run into
def main():
"""Main function to generate fuzzed test vectors."""
# Parse command-line arguments
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ tasks.register<JavaExec>("runTests") {
dependsOn("copyKeysJSON")
mainClass.set("TestsFromDafny")
classpath = sourceSets["test"].runtimeClasspath
// Increase stack size for large-scale fuzz testing with 10,000+ test vectors
jvmArgs("-Xss16m")
}

tasks.register<Copy>("copyKeysJSON") {
Expand All @@ -111,4 +113,6 @@ tasks.register<Copy>("copyKeysJSONCurr") {

application {
mainClass.set("ImplementationFromDafny")
// Increase stack size for large-scale fuzz testing with 10,000+ test vectors
applicationDefaultJvmArgs = listOf("-Xss16m")
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
<TargetFrameworks>net6.0;net48</TargetFrameworks>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<OutputType>Exe</OutputType>
<!-- Increase stack size for large-scale fuzz testing with 10,000+ test vectors -->
<StackReserveSize>16777216</StackReserveSize>
</PropertyGroup>

<PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@
The MPL Test Vectors generates more than the default recursion of 1000.
MPL test vectors exceeds Python's recursion limit when parsing the JSON, which needs >1 call per test vector.
(Other Crypto Tools languages are limited by memory; Python's explicit limit on function calls is unique.)
When using this internal Crypto Tools TestVectors library, set recursion limit to 10,000.
(This value is totally arbitrary and should be increased if this isn't enough.)
"""
sys.setrecursionlimit(10000)
sys.setrecursionlimit(100000) #previous recursion limit 10,000

# Initialize generated Dafny
from .internaldafny.generated import module_
Expand Down
Loading