Skip to content

Add P25 voice decryption support (AES-256, DES-OFB, ADP/RC4)#1112

Draft
blantonl wants to merge 3 commits intoTrunkRecorder:masterfrom
blantonl:add-p25-decryption
Draft

Add P25 voice decryption support (AES-256, DES-OFB, ADP/RC4)#1112
blantonl wants to merge 3 commits intoTrunkRecorder:masterfrom
blantonl:add-p25-decryption

Conversation

@blantonl
Copy link
Copy Markdown
Contributor

@blantonl blantonl commented Mar 27, 2026

Summary

  • Ports the complete OP25 decryption stack into trunk-recorder's bundled op25_repeater library
  • Supports real-time decryption of encrypted P25 voice traffic for Phase 1 (FDMA) and Phase 2 (TDMA), provided the encryption key is known and configured
  • Encryption keys are specified per-system via a dedicated JSON file referenced in config.json as "encryptionKeysFile"
  • Three algorithms supported: AES-256 (algid 0x84), DES-OFB (algid 0x81), ADP/RC4 (algid 0xAA)

Key changes

  • New crypto algorithm files (p25_crypt_aes, p25_crypt_des, p25_crypt_adp) with abstract base class and factory pattern
  • Wired crypt_key()/crypt_reset() through p25_frame_assembler_impl to p25p1_fdma and p25p2_tdma — the critical missing link that was preventing decryption from working
  • Per-system encryption key file loading from JSON config
  • Keys are passed to the frame assembler on each call start

Configuration

Add encryptionKeysFile to your system config:

{
  "systems": [{
    "type": "p25",
    "encryptionKeysFile": "/path/to/keys.json",
    ...
  }]
}

Key file format (see examples/encryption_keys.json):

{
  "keys": [
    { "keyid": "0x0001", "algid": "0x84", "key": "0123456789ABCDEF..." },
    { "keyid": "0x0002", "algid": "0x81", "key": "0123456789ABCDEF" },
    { "keyid": "0x1b50", "algid": "0xaa", "key": "0123456789" }
  ]
}

Test plan

This PR requires significant testing across all three encryption algorithms before merging.

  • Test AES-256 (algid 0x84) decryption with known key on a live P25 system — verify clear audio output
  • Test DES-OFB (algid 0x81) decryption with known key on a live P25 system — verify clear audio output
  • Test ADP/RC4 (algid 0xAA) decryption with known key on a live P25 system — verify clear audio output
  • Test Phase 1 (FDMA) encrypted calls
  • Test Phase 2 (TDMA) encrypted calls
  • Verify unencrypted calls are unaffected when keys file is configured
  • Verify behavior when no encryptionKeysFile is specified (should work as before)
  • Verify behavior with incorrect/mismatched keys (should produce garbled audio, not crash)
  • Build test on Linux (Ubuntu 22.04+)
  • Build test on macOS

lindsay and others added 3 commits March 27, 2026 11:13
Adds find_unit_tag_ota() through the UnitTags/System interface to resolve
over-the-air aliases for unit IDs. The OTA alias is propagated via the
tag_ota field in Call_Source, included in call JSON output, and sent as
the srcId_alias field in Broadcastify uploads.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Provides a downloadable patch for users who want to test the feature
before it is merged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Port complete decryption stack from OP25 into trunk-recorder's bundled
op25_repeater library. Supports real-time decryption of encrypted P25
voice traffic for Phase 1 (FDMA) and Phase 2 (TDMA), provided the
encryption key is known and configured.

Encryption keys are specified per-system via a dedicated JSON file
referenced in config.json as "encryptionKeysFile".

Changes:
- Add p25_crypt base types, abstract algorithm class, and factory
- Add AES-256 OFB, DES-OFB, and ADP/RC4 algorithm implementations
- Replace monolithic p25_crypt_algs with extensible factory pattern
- Wire crypt_key/crypt_reset through p25_frame_assembler_impl to
  p25p1_fdma and p25p2_tdma (the critical missing link)
- Add encryption key file loading to System config
- Pass keys to frame assembler on call start
- Include example encryption_keys.json
@TheGreatCodeholio
Copy link
Copy Markdown
Contributor

I like this idea to add the functionality for decryption. Unsure how to best test this. I guess best way is to just make sure non-encrypted calls aren't affected and all other current functionality stays the same.

@Dygear
Copy link
Copy Markdown
Contributor

Dygear commented Apr 1, 2026

I have a system I can test this on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants