-
Notifications
You must be signed in to change notification settings - Fork 21
Android test fixes and add Android FIPS Ready workflow #209
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
dc5fcfd
JCE: replace non-wolfJCE SecureRandom in FIPS mode instead of throwing
cconlon e8c6eea
Tests: handle ECC curves unsupported by SP math in KeyPairGenerator t…
cconlon c67e536
Tests: use Rule for ChaCha/Des3 availability instead of BeforeClass A…
cconlon 3458cdf
Android: add BKS KeyStore conversion script and update README
cconlon 38ee4ae
CI: add Android FIPS Ready workflow with two-pass hash and BKS support
cconlon a8add7d
Tests: retry RSA key gen once on transient PRIME_GEN_E in FIPS mode
cconlon 9f85f39
Security: pin Bouncy Castle version and verify SHA-256 hashes on down…
cconlon e8b5ee2
Android: replace jcenter() with mavenCentral(), migrate to AndroidX (…
cconlon f949f66
Tests: relax KEK cache timing assertion to avoid flaky CI failures
cconlon 18cbeed
CI: update Ant version to 1.10.16 (1.10.15 removed from Apache CDN)
cconlon File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,209 @@ | ||
| name: Android FIPS Ready Gradle Build and Test | ||
|
|
||
| on: | ||
| push: | ||
| branches: [ 'master', 'main', 'release/**' ] | ||
| pull_request: | ||
| branches: [ 'master' ] | ||
|
|
||
| concurrency: | ||
| group: android-fips-${{ github.head_ref || github.ref }} | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| build_wolfcryptjni_fipsready: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Clone wolfcrypt-jni | ||
| uses: actions/checkout@v4 | ||
|
|
||
| # Free up disk space to prevent emulator from failing | ||
| - name: Free up disk space | ||
| run: | | ||
| sudo rm -rf /usr/share/dotnet | ||
| sudo rm -rf /usr/local/lib/android/sdk/ndk | ||
| sudo rm -rf /opt/ghc | ||
| sudo rm -rf /opt/hostedtoolcache/CodeQL | ||
| sudo docker image prune --all --force | ||
| df -h | ||
|
|
||
| # Get latest stable wolfSSL version for FIPS Ready download | ||
| - name: Get latest wolfSSL stable version | ||
| id: wolfssl-version | ||
| run: | | ||
| LATEST=$(curl -s -H "Authorization: token ${{ github.token }}" \ | ||
| "https://api.github.com/repos/wolfSSL/wolfssl/tags?per_page=100" | \ | ||
| jq -r '.[].name | select(endswith("-stable"))' | \ | ||
| sort -V | tail -1 | sed 's/^v//;s/-stable$//') | ||
| if [ -z "$LATEST" ]; then | ||
| echo "Failed to determine latest wolfSSL stable version" >&2 | ||
| exit 1 | ||
| fi | ||
| echo "version=$LATEST" >> $GITHUB_OUTPUT | ||
| echo "wolfSSL stable version: $LATEST" | ||
|
|
||
| # Cache wolfSSL FIPS Ready archive | ||
| - name: Cache wolfSSL FIPS Ready archive | ||
| uses: actions/cache@v4 | ||
| id: fips-cache | ||
| with: | ||
| path: wolfssl-fips-ready.zip | ||
| key: wolfssl-fips-ready-${{ steps.wolfssl-version.outputs.version }} | ||
|
|
||
| # Download wolfSSL FIPS Ready if not cached | ||
| - name: Download wolfSSL FIPS Ready | ||
| if: steps.fips-cache.outputs.cache-hit != 'true' | ||
| run: | | ||
| VERSION="${{ steps.wolfssl-version.outputs.version }}" | ||
| URL="https://www.wolfssl.com/wolfssl-${VERSION}-gplv3-fips-ready.zip" | ||
| echo "Downloading: $URL" | ||
| wget -q "$URL" -O wolfssl-fips-ready.zip | ||
|
|
||
| # Extract wolfSSL FIPS Ready to expected location | ||
| - name: Extract wolfSSL FIPS Ready | ||
| run: | | ||
| unzip -q wolfssl-fips-ready.zip -d /tmp/wolfssl-fips-extract | ||
| EXTRACTED_DIR=$(find /tmp/wolfssl-fips-extract -mindepth 1 -maxdepth 1 -type d | head -1) | ||
| echo "Extracted directory: $EXTRACTED_DIR" | ||
| ls "$EXTRACTED_DIR/wolfcrypt/src/" | head -5 | ||
| mv "$EXTRACTED_DIR" IDE/Android/app/src/main/cpp/wolfssl | ||
|
|
||
| # Configure CMakeLists.txt for FIPS Ready build | ||
| - name: Configure for FIPS Ready | ||
| run: | | ||
| sed -i 's/set(WOLFSSL_PKG_TYPE "normal")/set(WOLFSSL_PKG_TYPE "fipsready")/' \ | ||
| IDE/Android/app/src/main/cpp/CMakeLists.txt | ||
| grep 'WOLFSSL_PKG_TYPE' IDE/Android/app/src/main/cpp/CMakeLists.txt | ||
|
|
||
| # Patch MainActivity to auto-trigger WolfCryptProvider on launch, | ||
| # so FIPS error callback fires and prints the expected hash to logcat | ||
| # without needing a button press. | ||
| - name: Patch MainActivity for auto FIPS hash detection | ||
| run: | | ||
| sed -i 's/button.setOnClickListener(buttonListener);/button.setOnClickListener(buttonListener);\n\n try { testFindProvider(null); } catch (Exception e) { e.printStackTrace(); }/' \ | ||
| IDE/Android/app/src/main/java/com/example/wolfssl/MainActivity.java | ||
|
|
||
| # Setup Java with Gradle caching | ||
| - name: Setup java | ||
| uses: actions/setup-java@v4 | ||
| with: | ||
| distribution: 'zulu' | ||
| java-version: '21' | ||
| cache: 'gradle' | ||
|
|
||
| # Build all targets | ||
| - name: Gradle Build (pass 1 - placeholder hash) | ||
| run: cd IDE/Android && ./gradlew --build-cache assembleDebug assembleDebugUnitTest assembleDebugAndroidTest | ||
|
|
||
| # Enable KVM for hardware acceleration | ||
| - name: Enable KVM | ||
| run: | | ||
| echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules | ||
| sudo udevadm control --reload-rules | ||
| sudo udevadm trigger --name-match=kvm | ||
|
|
||
| # Cache AVD snapshot for faster emulator boot | ||
| - name: AVD cache | ||
| uses: actions/cache@v4 | ||
| id: avd-cache | ||
| with: | ||
| path: | | ||
| ~/.android/avd/* | ||
| ~/.android/adb* | ||
| key: avd-wolfcryptjni-fips-30-x86_64-google_apis-v1 | ||
|
|
||
| # Create AVD and generate snapshot for caching | ||
| - name: Create AVD and generate snapshot | ||
| if: steps.avd-cache.outputs.cache-hit != 'true' | ||
| uses: reactivecircus/android-emulator-runner@v2.37.0 | ||
| with: | ||
| api-level: 30 | ||
| arch: x86_64 | ||
| target: google_apis | ||
| force-avd-creation: false | ||
| emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none | ||
| disable-animations: true | ||
| script: echo "Generated AVD snapshot for caching" | ||
|
|
||
| # Launch app briefly to capture FIPS in-core hash from logcat. | ||
| # The FIPS error callback prints the expected verifyCore hash on | ||
| # startup if there is a mismatch. | ||
| - name: Capture FIPS in-core hash | ||
| id: fips-hash | ||
| uses: reactivecircus/android-emulator-runner@v2.37.0 | ||
| timeout-minutes: 5 | ||
| with: | ||
| api-level: 30 | ||
| arch: x86_64 | ||
| target: google_apis | ||
| force-avd-creation: false | ||
| emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none | ||
| disable-animations: true | ||
| script: | | ||
| adb wait-for-device | ||
| adb logcat -c | ||
| cd IDE/Android && ./gradlew installDebug --no-daemon --no-watch-fs | ||
| adb shell am start -W -n com.example.wolfssl/.MainActivity | ||
| for i in 1 2 3 4 5 6; do sleep 5; adb logcat -d | grep -q 'hash = [A-Fa-f0-9]\{64\}' && break; echo "Waiting for FIPS hash ($i/6)..."; done | ||
| adb logcat -d > /tmp/logcat_hash.txt 2>&1 | ||
| HASH=$(grep -o 'hash = [A-Fa-f0-9]\{64\}' /tmp/logcat_hash.txt | head -1 | sed 's/hash = //'); if [ -n "$HASH" ]; then echo "Captured FIPS hash: $HASH"; echo "hash=$HASH" >> $GITHUB_OUTPUT; else echo "No FIPS hash found in logcat, assuming existing hash is correct"; echo "hash=" >> $GITHUB_OUTPUT; fi | ||
|
|
||
| # Update FIPS hash in CMakeLists.txt and rebuild if needed | ||
| - name: Rebuild with correct FIPS hash | ||
| if: steps.fips-hash.outputs.hash != '' | ||
| run: | | ||
| HASH="${{ steps.fips-hash.outputs.hash }}" | ||
| echo "Updating FIPS hash to: $HASH" | ||
| sed -i "s/WOLFCRYPT_FIPS_CORE_HASH_VALUE=[A-Fa-f0-9]*/WOLFCRYPT_FIPS_CORE_HASH_VALUE=$HASH/g" \ | ||
| IDE/Android/app/src/main/cpp/CMakeLists.txt | ||
| cd IDE/Android && ./gradlew --build-cache assembleDebug assembleDebugUnitTest assembleDebugAndroidTest | ||
|
|
||
| # Generate BKS KeyStore files for PKIX tests | ||
| - name: Generate BKS KeyStore files | ||
| run: | | ||
| # Bouncy Castle version may need periodic updates | ||
| BCPROV_JAR="bcprov-jdk18on-1.78.1.jar" | ||
| BCPROV_URL="https://repo1.maven.org/maven2/org/bouncycastle/bcprov-jdk18on/1.78.1/${BCPROV_JAR}" | ||
| wget -q "$BCPROV_URL" -O "/tmp/${BCPROV_JAR}" | ||
| wget -q "${BCPROV_URL}.sha256" -O "/tmp/${BCPROV_JAR}.sha256" | ||
| (cd /tmp && echo "$(cat ${BCPROV_JAR}.sha256) ${BCPROV_JAR}" | sha256sum -c -) | ||
| cd examples/certs && ./convert-to-bks.sh "/tmp/${BCPROV_JAR}" | ||
|
|
||
| # Run instrumented tests on Android emulator | ||
| - name: Run Android Instrumented Tests | ||
| uses: reactivecircus/android-emulator-runner@v2.37.0 | ||
| timeout-minutes: 15 | ||
| with: | ||
| api-level: 30 | ||
| arch: x86_64 | ||
| target: google_apis | ||
| force-avd-creation: false | ||
| emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none | ||
| disable-animations: true | ||
| script: | | ||
| adb wait-for-device | ||
| adb shell mkdir -p /data/local/tmp/examples/certs/intermediate | ||
| adb shell mkdir -p /data/local/tmp/examples/certs/rsapss | ||
| adb shell mkdir -p /data/local/tmp/examples/certs/crl | ||
| adb push ./examples/certs/ /data/local/tmp/examples/ | ||
| adb logcat -c | ||
| cd IDE/Android && ./gradlew connectedDebugAndroidTest --no-daemon --no-watch-fs || { adb logcat -d > /tmp/logcat.txt 2>&1; echo "=== LOGCAT (errors) ==="; grep -i "exception\|error\|fatal" /tmp/logcat.txt || true; exit 1; } | ||
| adb logcat -d > /tmp/logcat.txt 2>&1 || true | ||
| # Clean up emulator processes. Safe to kill -9 since | ||
| # -no-snapshot-save is used (no snapshot to corrupt). | ||
| pgrep -f '[q]emu-system' | xargs -r kill -9 2>/dev/null || true | ||
| pgrep -f '[c]rashpad' | xargs -r kill -9 2>/dev/null || true | ||
| sleep 2 | ||
|
|
||
| # Upload test reports even on failure | ||
| - name: Upload Test Reports | ||
| uses: actions/upload-artifact@v4 | ||
| if: always() | ||
| timeout-minutes: 5 | ||
| with: | ||
| name: android-fips-ready-test-reports | ||
| path: | | ||
| IDE/Android/app/build/reports/androidTests/ | ||
| /tmp/logcat.txt | ||
| /tmp/logcat_hash.txt | ||
| retention-days: 14 | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.