CVE-2025-32330 AI-generated analysis
platform/frameworks/base, packages/SettingsLib (Bluetooth LE audio broadcast / audio sharing)
Replaces the LE audio broadcast (audio sharing) password generator in SettingsLib's LocalBluetoothLeBroadcast, which derived a 12-character hex string from UUID.randomUUID(), with a 16-character password drawn from an 89-symbol alphabet using java.security.SecureRandom.
Root cause
LocalBluetoothLeBroadcast.generateRandomPassword() built the broadcast password by calling UUID.randomUUID().toString() and concatenating substring(0, 8) and substring(9, 13), i.e. 12 hexadecimal characters (16-symbol alphabet, at most 48 bits of entropy). The commit, tagged #security and titled 'Improve audio sharing password handling', replaces this generator (bulletin type ID, High).
How the fix works
- packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java: adds constants VALID_PASSWORD_CHARACTERS (26 uppercase + 26 lowercase + 10 digits + 27 punctuation characters = 89 symbols) and PASSWORD_LENGTH = 16.
- LocalBluetoothLeBroadcast.generateRandomPassword(): rewritten to create a java.security.SecureRandom, loop PASSWORD_LENGTH times, pick random.nextInt(VALID_PASSWORD_CHARACTERS.length()) and append the chosen character to a StringBuilder, returning the 16-character string (about 103 bits of entropy versus about 48 before).
- Imports: java.security.SecureRandom added; on Android 14 the java.util.UUID import is removed and the method made private static. The Android 15 commit keeps the instance method signature and does not touch the UUID import.
- Commit message states this is a backport of ag/31824318 and that ag/31424453 (same bug) is superseded and need not be backported.
Completeness
- The fix changes only how the password string is generated; it does not change where or how the password is stored, displayed, or passed to BluetoothLeBroadcast (not shown in the diff).
- Only generateRandomPassword() is touched. The class still imports java.util.concurrent.ThreadLocalRandom and defines DEFAULT_CODE_MIN = 1000 / DEFAULT_CODE_MAX = 9999 (visible in the Android 14 r29 context); the material does not show what these are used for.
- No validation or minimum-strength check is added for passwords supplied by other paths, if any exist; the material does not show such paths.
Behavior changes
- Generated broadcast passwords change from 12 hex characters to 16 characters that may include uppercase and lowercase letters, digits and punctuation such as ! @ # $ % ^ & * ( ) - _ = + [ ] { } | ; : , . < > ? /.
- Password generation now uses java.security.SecureRandom instead of UUID.randomUUID().
- Any UI or consumer that assumed a 12-character or hex-only password would observe the new format; the material does not show such consumers.
Per major
- Android 14: same fix: commit a9d98a5646f1 in android-security-14.0.0_r22 (cherry-pick, Merged-In If2ad220d...), method made private static and UUID import removed; 8/8 lines of the patched region present at android-security-14.0.0_r29.
- Android 15: same fix (adapted context): commit 5b10581d2a91 in android-security-15.0.0_r10, identical generator body, method stays non-static and the UUID import is not touched; 8/8 lines present at android-security-15.0.0_r17.
- Android 16: not affected (not listed by the bulletin); the patched region (8/8 lines) is present at android-security-16.0.0_r8.
- Android 17: not affected (not listed by the bulletin); the patched region (8/8 lines) is present at android-security-17.0.0_r1.
Unknowns
- Where the generated password is consumed (e.g. how it is passed to BluetoothLeBroadcast or shown to the user) and whether any length/charset limit applies there.
- The concrete attack scenario behind the High/ID rating (the material gives only the weak-generation diff).
- What DEFAULT_CODE_MIN/DEFAULT_CODE_MAX and the retained ThreadLocalRandom import are used for in this class, and whether they produce any credential.