codec2
codec2 copied to clipboard
Use case for python, encryption and decryption features.
Hello @aarmono Thank you for this awesome library.
I am new to audio codecs and how to use them, but i followed your tutorials and it seemed to work in raspberry pi using build-root configurations. (i used your given images for PI).
I am trying to implement the same functionality in python as I am much familiar with it. Can you guide me with a simple code on how I would implement this using python?
If it's a big thing to ask then can you just guide me on how to use encryption on voice data? Also if not python then just on how to use this repo https://github.com/aarmono/crypto_transceiver
My scenario is like this.
- I am using a raspberry pi with the same setup as yours, but I need to perform other tasks as well so I am using python.
- I am recording a bit of digital audio using this "pip installl sounddevice" library of python and then trying to encrypt it but no luck. because the block cipher is changing the data which I am unable to change to audio.
Thank you
If Python is a hard requirement then you have a couple options:
- Use python C bindings to wrap the codec2 library. If you do this you would likely have to re-implement the crypto_tx and crypto_rx functionality in Python. I've never done anything that required python C bindings so I wouldn't be able to offer much help on this option, and beyond that it sounds like a lot of work
- Write a wrapper class that spawns crypto_tx/crypto_rx executables using the subprocess module. This class could create/modify the .ini using the Configparser library to change settings and redirect standard input/output to get access to the audio streams. This is probably what I would do even though it's a bit of a hack and requires that you be able to build the crypto_transceiver repo. But it guarantees compatibility.
As for how to use the crypto_transceiver repo:
- I built everything out of $HOME/Git, and the cmake scripts look for things in that location
- Clone my fork of the codec2 project and the crypto_transceiver project in $HOME/Git
- So then you have two directories: $HOME/Git/codec2 and $HOME/Git/crypto_transceiver
Then build codec2:
cd $HOME/Git/codec2
mkdir build_linux
cd build_linux
cmake ..
make
Then build crypto_transceiver:
cd $HOME/Git/crypto_transceiver
mkdir build_linux
cd build_linux
cmake ..
make
That will (hopefully) get you the crypto_tx and crypto_rx binaries in $HOME/Git/crypto_transceiver/build_linux
To run them, they take one command line argument, which is the path where their respective .ini file (crypto_tx.ini and crypto_rx.ini) is located. You may need to modify those files to change key locations and the like They take audio input on stdin and output it on stdout. Voice data is a 8KHz 1 channel audio encoded as 16-bit unsigned integers. The encrypted data is 48KHz 1 channel audio also encoded as 16-bit unsigned integers.
I was just using the aplay, arecord, and sox command line tools to get audio data to pipe into crypto_tx and crypto_rx. The transmit.sh, receive.sh, and record_voice.sh scripts contain the settings I used and show you how the data is piped into and out of crypto_tx and crypto_rx. You can probably get them to work with some slight tweaks to work with your particular linux environment and avoid the whole Python thing entirely.
Hope this helps.
Thank You @aarmono for the neat explanation. Very much helpful.
I am also going to drop python and work only in C. Though I have a few doubts.
-
Is encryption happening on the codec level when I read the code of crypto_tx.c file i saw this function called serval time "freedv_set_crypto".
-
As you have written the code based on std-out/in concept and piped the output and input. If I want to use STM32 for the same purpose how can I do it? I saw how to compile and run codec2 onto STM32 with the SM1000 method given in the blog post but I think the original code lacks the encryption part.
-
Can you explain a bit about encryption only how to achieve this with a sample packet of a recorded audio and then convert that back to encrypted audio? If we do not use or use codec2.
Thank you so much for this great work.
- Yes: my fork of the codec2 library adds the support for the encryption.
- Probably the easiest way to get it working on the SM1000 is to use that hardware's project and try to get my fork of the codec2 library working in that codebase. Though doing so might be tricky, since the CPU might not be powerful enough to do the encryption as-is without optimizations. More on this below.
- The encryption works by the crypto_tx/crypto_rx functions reading a key from the SD card and calling the freedv_set_crypto codec2 function (which only exists in my fork of the codec2 project) with the key (and for crypto_tx, and a random initialization vector). Then every minute or when there is a pause in the audio crypto_tx will generate a new initialization vector. This is to make it more difficult for a third-party to break the encryption during a long transmission. If you have a packet of recorded audio, then you call freedv_tx with it, and it will return you a packet of encrypted digital audio that you would then send out onto your audio device. If you have a packet of encrypted digital audio, then you call freedv_rx with it, and it will return you a packet of analog audio that you would then send out onto your other audio device.
From a very quick look at the sm1000_main.c file in the SM1000 project, it looks like that code has a very similar structure to crypto_tx and crypto_rx, except that it combines both TX and RX into one function. In certain ways that actually makes your job easier. However there are some things you'd need to do:
- It doesn't look like it supports the 2400B mode that my project uses. Hopefully that's not due to a hardware limitation
- You'll need to find a good source of randomness for the initialization vectors. Looks like STM32 has some support for hardware RNGs on some of their chips. Don't know if the chip on the SM1000 has one though.
Here is what I would do to try to get the SM1000 working
-
Follow the instructions to build the SM1000 codebase using my codec2 fork (so it will use my version of codec2 with the encryption) and just see if it builds. Looks like the SM1000 codebase is all part of the same codec2 repo, so it should.
-
Once that builds, in the set_freedv_mode function, hardcode setting it to FREEDV_MODE_2400B
f = freedv_open(FREEDV_MODE_2400B); *n_samples = freedv_get_n_speech_samples(f);
-
Rebuild, see it it builds
-
Since you have a Pi as well, try to get the two talking to each other. Turn off encryption on the Pi. You can do this by commenting out the KeyFile config option in the .ini files
-
See if your SM1000 and Pi can talk to each other. With encryption disabled they should. If they don't then there may be a problem with that mode on the SM1000.
-
Now try to get the encryption working. Hardcode a key for the time being unless you know how to load one onto the flash, and call freedv_set_crypto with it in that same set_freedv_mode function. Also hardcode an IV. Compile, see if it builds.
-
Use the same key as you hardcoded on the Pi and see if you can get the two to talk to each other. If that doesn't work, then you at least know where the problem lies
Hello
Thanks again for the amazing explanation I will try to make this for SM1000 as well if everything works I will send you one pull request for SM1000 as well.
Thank you
If Python is a hard requirement then you have a couple options:
- Use python C bindings to wrap the codec2 library. If you do this you would likely have to re-implement the crypto_tx and crypto_rx functionality in Python. I've never done anything that required python C bindings so I wouldn't be able to offer much help on this option, and beyond that it sounds like a lot of work
- Write a wrapper class that spawns crypto_tx/crypto_rx executables using the subprocess module. This class could create/modify the .ini using the Configparser library to change settings and redirect standard input/output to get access to the audio streams. This is probably what I would do even though it's a bit of a hack and requires that you be able to build the crypto_transceiver repo. But it guarantees compatibility.
As for how to use the crypto_transceiver repo:
- I built everything out of $HOME/Git, and the cmake scripts look for things in that location
- Clone my fork of the codec2 project and the crypto_transceiver project in $HOME/Git
- So then you have two directories: $HOME/Git/codec2 and $HOME/Git/crypto_transceiver
Then build codec2:
cd $HOME/Git/codec2 mkdir build_linux cd build_linux cmake .. makeThen build crypto_transceiver:
cd $HOME/Git/crypto_transceiver mkdir build_linux cd build_linux cmake .. makeThat will (hopefully) get you the crypto_tx and crypto_rx binaries in $HOME/Git/crypto_transceiver/build_linux
To run them, they take one command line argument, which is the path where their respective .ini file (crypto_tx.ini and crypto_rx.ini) is located. You may need to modify those files to change key locations and the like They take audio input on stdin and output it on stdout. Voice data is a 8KHz 1 channel audio encoded as 16-bit unsigned integers. The encrypted data is 48KHz 1 channel audio also encoded as 16-bit unsigned integers.
I was just using the aplay, arecord, and sox command line tools to get audio data to pipe into crypto_tx and crypto_rx. The transmit.sh, receive.sh, and record_voice.sh scripts contain the settings I used and show you how the data is piped into and out of crypto_tx and crypto_rx. You can probably get them to work with some slight tweaks to work with your particular linux environment and avoid the whole Python thing entirely.
Hope this helps.
Yes it helped and i successfully compiled and tested everything worked as you mentioned. Tested with the TRS cable and everything worked the encryption and decryption.
Though have one question , will it work on GSM network with two phones. [Edited] I found your comment on Youtube **It will probably work on a landline phone since it works very similar to the old 80s style computer modems. It might work on a cell phone, but there are two issues you might have with cell phones:
- Cell phones also digitally compress the audio, and the quality may not be high enough to be able to decompress the data on the other side
- The phone may apply some noise reduction to the sound coming in from the headset connector that affects the ability to decode the signal**
on one of your video.
But is it possible like, theoretically what will be the changes we can make to make this work on GSM.
Thanks again.
Re: GSM
I haven't tested it much, but sox and/or ffmpeg has a version of the GSM audio codec built in that I tried, and I couldn't get it to work. I also tried it once with my phone without success, but I didn't investigate whether or not there was a phone setting I could adjust to make it work.
Theoretically one of the other codec2 modes might work better, and that might be something you could experiment with on your SM1000 or even the freedv_gui PC software. If one of those other modes worked then on my end it would just be a matter of adding the encryption support to it. Also possible it might be sensitive to the gsm codec bit rate. Don't know if different providers use different bit rates or if they adjust it based on signal strength.
But I haven't spent much time on trying to make it work over cellular networks for the simple reason that with modern smart phones and cellular data networks there are much better options available. Whereas with radios it was all proprietary and/or insecure.