Shared publicly  - 
Secure/push messages in +CyanogenMod

We've been focusing on data security lately; +Steve Kondik got the ball rolling with Privacy Guard. And obviously, recent events have made privacy concerns a global discussion.

The Privacy Guard contribution is the philosophy I like to  to see in these types of data security implementations: seamless protection of the user data. If it's a pain to use, or if it breaks third party apps, it's going to be a negative experience, and we're doing it wrong.

One of the interesting developments of the past couple weeks is that iMessage, is not snoopable by a third party, not even Apple (or so they would have you believe ;).

Regardless of whether that is true; I love the design philosophy of iMessage: it works transparently, and encrypts the user's message between iOS users and fails over to SMS as needed. Frictionless.

I'd thrown a poll out there, to see what sort of cohesiveness +CyanogenMod  users have. Surprisingly high. Many +CyanogenMod  text a lot with other +CyanogenMod users.
(Which makes sense, as our growth to 7M users is entirely organic and word of mouth)

Anyways, TL;DR. I've built out a secure/push based messaging plugin for CyanogenMod. Messages between two CyanogenMod will be encrypted end to end and sent over GCM. It's built into the framework; so it works transparently, even with third party apps. (This is actually one of the cooler points IMO, and I do a lot of testing with GoSMS, etc)

It's basically PGP (encryption + authenticity) for text messages, built into the system.

There are two minor changes to the telephony and framework to support this:

Add Middleware hooks to IccSmsInterfaceManagerProxy. This allows a sent SMS message to be intercepted and rewritten or sent over another transport.

Add other various framework support bits (new permissions). Grant system apps priority in case of ordered broadcast priority tie.

Here's the source for the app/plugin, which is still under heavy development.

At this point, I'm looking to get some feedback, discussion, thoughts, etc on this project. Not ready for active testing yet.
Ed Bassi's profile photoSHUBHAM PRAJAPATI's profile photoSatadru Pramanik's profile photoJulien Lamy (JuL)'s profile photo
How do peers know the other end is or isn't PushSms enabled? Do they register with a centralized directory or do they do some peer to peer discovery/testing before-hand?
Wow truly awesome. Is this just for security, or are there ( planned) feature enhancements as well like delivered, seen etc.?
+Cole Mickens We will probably need to build in visual cues into the CM Messaging app. There are none right now. Other than logcat :)
+Koushik Dutta Sorry, I meant internally or at a more technical level. Does one have to manually choose when to use this, or does it auto-negotiate and auto-enhance to encrypt if possible? If the latter, this would presumably only work if something somewhere knows that both parties have this modified framework ahead of time, right? So that you hook can either decide to intercept and rewrite or ignore it for a non-CM user, etc. Do you have a little cloud service that can GET/POST to /IsPushSmsEnabled?number=8675309 to signal this or am I over complicating this in my head?
Been following the middleware commit on gerrit for the past week. Great stuff man. 
Awesome stuff, one of many reasons I love running CM and CM based builds. I do have one question though. Would picture messages also be encrypted?
lol ok. Just curious, why is it the devil? Just a coding nightmare?
Awesome, awesome cool. Seriously, not just a good idea, seamlessly executed (for the user). Don't know if I appreciate it more from a UX experience or from a clean architecture standpoint. Very cool. Though I'm still going down with Voice, even after they Reader it.
+Koushik Dutta this wouldn't work with non-CM users right? Would it be possible to also have a third party app that anyone can install to use the service as well? 
+David Gross I definitely want to get MMS done, but MMS data formats are highly variable based on carrier, from what I understand. And a pain to parse too.
This is awesome! However none of my friends run cyanogenmod :(
/tinfoilhat So if the central public keystore is MitM'd or DoS'd, users either have their texts snooped or are failed over to cleartext, yeah?

Any chance of some sort of clever key exchange mechanism that doesn't rely on a centralized database?

(Note: I realize that either way, GCM is a central point of failure, so I'm really just asking out of curiosity.)
+Nick Piepmeier We were just talking about this.
I'm going to implement a secondary/confirmation key exchange that also goes over SMS in addition to GCM to prevent MITM.
Well, then you'd need to compromise two transports to MITM.

Furthermore, as a stretch goal, this should work without GCM by sending encrypted SMS similar to TextSecure.
So, this basically trusts the intermediate server to give you the right public key? And tries to reinvent SSL for the actual protocol...
+Nikolay Elenkov Basically.

Can't use SSL over a datagram-style transport though, much less create a TCP connection between two phones ;)

On the first point, there will be two points of confirmation. One intermediary server (to see if the peer is supported), and also a confirmation key exchange over SMS to deal with MITM. See my previous comment.
Just my 2 cents. What would happen if i send pushsms to  a non-smart phone, Black berry,  Nokia, Windows phone.
Do he/she get garbage? 
You can (DTLS), but that's another can of worms. The framework support, etc. is nice, but this needs to be based on an actual cryptographic protocol  to be useful. Preferably using direct key negotiation without a middleman. Encryption needs authentication (HMAC, etc.)  

BTW, why this: secureRandom.setSeed(new BigInteger(256, new Random()).toByteArray());? Using `new SecureRandom()` should be sufficient and it would seed from /dev/urandom, etc. automatically. java.util.Random is  a poor source of entropy.
+Nikolay Elenkov For some reason i thought the new SecureRandom() constructor was unavailable on Android. Let me double check.

Direct key negotiation is tricky up front: you run the risk of sending garbage to users that don't support the protocol. That is not a good user experience. That's why the first key exchange is done via an intermediary which confirms the other side supports PushSMS, and a redundant key exchange will be done directly afterwards.
You're the man! I love these privacy features you guys are implementing! 
Say I'm running Cyanogenmod and a friend is running paranoid. 
Would this work between us? Last I checked both were using the same mms.apk. 
Sounds awesome to me, look forward to trying this out. 
No turnkey solution yes, but it is better to start with an actual protocol (like OTR). Or should I just comment on issue #1 :)

Other random things: Cipher.getCipher("AES") may give you different things on  different platforms, it's better to specify padding and mode explicitly; should use random IV and make it part of the protocol; should use another key for HMAC; local private keys should be stored in the KeyChain (generation might not be supported in 4.2 though). 
Additional security is always good. I would suggest that public keys should have the option to be cached, and more methods of key exchange be available through some sort of secure api. So if I want to implement qr code exchange or whatever I can.

Also someway to confirm that the relevant encryption code isn't altered. 
Sal G
How in the world did you build this? I've been thinking of a way to implement this with my own built server. Let me know if I can help anyway with anything server/network related 
Great work as always +Koushik Dutta this is a real need , and something i was considering taking on myself, I appreciate you working on this and let me know if i can help in anyway 
This wouldn't work at all with Google voice would it?

+Nikolay Elenkov I'm by no means a crypto guru, which is why I've already contacted moxie about collaborating. He was pretty excited. The protocol is by no means final. I want to work towards something standardized.

+Lawrence Jacob Siebert they're cached.
I support this fully :-) take my money!
+Nicolas Finn nope, google voice does it's own thing. but the middleware changes could be used to build a google voice layer that works with normal SMS clients. That's actually something I had in mind, if I ever have the time.
Is this not in development for Google hangout?
Dude, awesome work and implementation plan.. :-) 
im new to all of this and my wife realy used all of this against me. would like to see who all has been tampering with my phones.
I find this fascinating. I figured it was something like this you were working on given some recent posts. Very cool work.

+Koushik Dutta for users who don't have unlimited text messages, what kind of usage impact might this have? Sounds like you'd be sending at least a few more SMS messages in the case it must go over SMS. And I'm guessing the encrypted messages themselves will be longer.
Developer like you really make android shine! Thanks for this thought and implementation. Maybe later google can make it as default feature in Android code base
+Paul Morris Yeah, I think the defaults should be sane: a regular user shouldn't ever be inconvenienced by secure messaging.

But it's also important to have settings that let you tweak the level of security by requiring a encrypted transport, etc. Those should be available for advanced users with stringent security requirements. (and not on by default, as message delivery may fail)
+Jonathan Berry Right now the encrypted content is not sent over SMS, it's sent over a data connection.

If using the SMS transport for encrypted messages, most texts should be fine with symmetric encryption (which only adds a few bytes overhead). So most encrypted text messages won't be cause extra sms usage, so long as there is sufficient space left. Ie, if the message is < 130 chars, it can probably be encrypted.
Seriously cool! Did you consider OTR instead of PGP? 
+Jonas Bengtsson The protocol isn't final. People that are more knowledgeable about crypto are working with me, and we'll work towards something more standardized (OTR was mentioned).

What I don't want is to make sacrifices to the detriment of the average user experience. It needs to be easy as texting now.
Well done +Koushik Dutta and all the +CyanogenMod crew. CM is rapidly becoming an example of Android phone "done right" and deserves to ship on a device soon. 
I look forward to this greatly.
This is awesome. This plus an app for our none CM friends.
Using a tcp connection between two devices (and multiple connections in case of group messaging I guess) will allow also tablet (or any wi-fi only device) to use this, right?

Once done the "one more thing" could be to have accessible API to check if a phone number is using this service and implement the client side also on iOS devices as a tweak for the messages application.
+Koushik Dutta I Misunderstood "much less create a TCP connection between two phones" you wrote in a previously reply. Now it make sense. Btw if you're not sending over SMS but data connection you still can use it on a wi-fi only device, right?
I wish that apps would then show encrypted messages first at garbled and then animation like they're decrypting it. Like in movies. Then I can pretend to be a secret agent that has a mission. Even if that mission is "Bring some milk when you get from work". 
Have you considered enabling Perfect Forward Secrecy to guard against passive data logging and late/forced key recovery?
How will private keys be propagated accross multiple devices?
Lol what a peculiar creature the poor thing doesn't know if its a cat or an octopus.
+Robert Foss I'd presume from standard practice that you wouldn't propogate the keys between devices, and would instead generate a new key on each device.

That potentially gets messy on reinstall, as users are updating their keys. That in turn means there is a valid attack by way of compromising the Google Account (or the server-side API) to substitute keys and mobile numbers.

On the topic of forward secrecy, I personally really think that's the way to go here. The biggest issue though is usability - the end user will not like the fact he cannot re-read SMS messages. And thus they will be decrypted and stored on the device in plaintext.

At the end of the day though, the key for this is stored on the device. CM users tend to run root apps. All it takes is one rogue app that steals the key, and it's game-over. The solution is to encrypt the private key using a password the user must enter to view messages, but this will end up being a weak password for convenience.

JM2C. I really like the concept, although have my hesitations about it being at all reliant on Google infrastructure. I am trying to think of a better model for working that wouldn't rely on a trusted server to give keys... My biggest concern tbh is that whoever controls the "service" can swap keys and phone numbers and Google account IDs. And while I'm sure nobody here would do that, and I'm not suggesting they would, I am sure certain companies could be strong-armed with court order.

Or some of the trusted individuals could be threatened, coerced, duped or forced into making the change. Or someone could find a vulnerability in the API and throw a new key in for every user, allowing them to decrypt any sent message.
Hey Koush, first off this is awesome! Google will be implementing something like this in the next 6 months I bet :). 

I'm curious though, have you considered people who may uninstall +CyanogenMod  in regards to the central authority? Is there a heartbeat, at what interval does the middleware check to see if a device is still available for Secure Text?

If I uninstall CM, and a minute later someone on CM tries to send me a text, will it try to go over Secure Text and fail? If it fails will it automatically fall back to SMS?
+Koushik Dutta congrats for the idea and the implementation! And yes, I can understand your frustration. I hope that you understand that I just wanted to ask a question, though, and I hope that this unpleasant situation can be left behind us. 

Keep up the good work and thanks for your effort!
+Nicholas Conner In the source is capability for acknowledgements (positive and negative). I am imagining that the system would detect a lack of acknowledgement (cloud to device messages are fairly fast), and then take action accordingly, perhaps sending over SMS.

Though this is a very good concern. The ability of a user to "stop" using the service, and have their data wiped off the server (if there must be a central server) would help here, but equally give rise to the challenge of trying to stop impersonation attacks.

I think if Google ever does implement something like this though, it will be seriously watered down, and involve the key being held or accessible by Google... As we all know they just love to access and trawl everything you do...
+Koushik Dutta
If I got it correctly, the system checks wheter the parties are registered with the CM servers or not, right?
If so, how could it establish which version is the other end running? How could you be sure there's not a CM10.0 or older (so not "scrambable") device?

+Pulser Villain
for what i've understood, aside the registration of the device, other functions will be point-to-point, with no server involved
+Daniele Pantaleo
Hmm that's definitely interesting. I see that Koush wants to use SMS as a second channel.

My concern is that without being "non user friendly" (ie. phones sending non-CM users unreadable coded messages to ask for keys to be sent by SMS), there will be a need to rely on the server for key exchange at some point...

If this is truly decentralised, I can actually see a few ways to remove reliance on a central server... A distributed hash table would be perfect here in my opinion. While the specifics would need a bit of time to figure out, I reckon it would be possible to use a DHT to store the user's key in the network, based upon their unique identifier (to keep this generic I won't say phone number, given tablets etc).

The user would sign their "update" with a key they defined when setting up the service (this key could be derived from an open source method that uses a number of device identifiers plus user provided identifier to set up a deterministic "master key").

This update updates the DHT with the latest details of the user's encrypted message support, perhaps adding another device, or changing key (due to a reinstall). The important bit is that they must use their deterministic key to sign this request, so another party cannot generate this same key to falsely sign and push a rogue update.

+1 for the Google Voice layer for normal SMS clients. Really hope you can make that happen! I don't understand why Google didn't do this from the very beginning...
+Daniele Pantaleo +Pulser Villain High level:

CM peers and their public keys are stored on a server.
Users looking to find peers hit the CM server, and find their registration info.
Users can then use that public key info to send GCM pushes to thier peer by hitting GCM directly.
The recipient of the GCM push will hit the server to confirm the public key of the sender.
If any message does not receive an ACK within a defined timeout, it is resent over SMS (cleartext). [1]

Yes, I realize this is susceptible to MITM if the server is compromised. :)

What I already had planned:

I want to also use the SMS channel to directly negotiate/confirm the key exchange, once the server and client have established that they are both in fact running the CM messaging stack. So, at this point, not only would the server need to be compromised, so would the carrier network in real time for a successful MITM.

Use peer to peer detection by throwing unseen whitespace into normal SMS. Can maybe also null terminate the data, and put extra data the terminator.

TextSecure compatibility (already contacted Moxie last week)

And good suggestions from other people:

Several people have pointed out I should use OTR instead of PGP for forward secrecy. I found a fairly nice java library on cypherphunks that I'll check out. Hopefully it runs on Android without too much trouble. My (understanding) and concern is that OTR sessions may not work so well on lossy transports, where if a message is lost, the continual diffie-hellman exchange is reset.

Also, its funny that you mention DHT. I JUST built a DHT client for Android a month ago, and was musing with +Steve Kondik yesterday, that it could be used for the basis of peer to peer lookup. (In fact, the bencoding classes I use in PushSMS are pulled from said torrent client :)

[1] Obviously there will need to be a not-on-by-default setting that prevents sending cleartext SMS altogether.
+Koushik Dutta can we somehow be assured you will maintain this feature in the long term? or stop being interested as with several of your code projects? 
not trying to pull your leg, just accessing how future proof this all idea is. thanks for your dedication.
if you need beta testers, i'm available (free sms/data plan)
+Koushik Dutta What about the option for a physical key exchange (via NFC, or qr code scan, etc) to be used for future messages (to take out the middleman server for between those two people)? I definitely like the premise behind what you're trying to accomplish. Kudos.
Actually, Steve's design does have an omission - unless I misunderstand Privacy Guard.  Right now, you have to intentionally select the apps to which you want to apply the Privacy Guard.  There needs to be a default that can be set.  So you can either be secure by default or be wide open by default.  Right now, things are insecure until you intentionally make them secure.  For me, this will be a tedious process.  With almost 200 apps installed, it will take a long time before I set everything up.  A default policy would allow me to secure things down and then open it up very slowly - and intentionally.  
+Fernando Miguel Fair question.

Well, the projects that I put out ot the open source community tend to get picked up and run with... See CWM, Superuser, AndroidAsync, Ion, UrlImageVIewHelper, etc. Very high adoption rates and contributors. Check the fork/star count.

It's the closed source stuff that I may lose interest in, that has no outlet of adoption ;)

This is open source, so even if I dropped off the face of the earth tomorrow, there's no reason the community couldn't pick this up and run with it. You can't put that on me :)
+Koushik Dutta not forcing you to commit to it, no one can do that, nor should. just wondering. 
I see lots of potential in this, but it will suffer lots of scrutiny from even more users, than those that complain about user stats/tracking.
Also it needs to be properly done so it withstands mit attacks.
 baby steps, ofc
+Koushik Dutta
Indeed, that's the biggest challege with OTR, in my eyes... SMS is a lossy medium, and arguably not even "best effort" service, particularly at new year time, when carriers delay messages to batch them together to try and stop the network falling apart.

RE DHT, that's quite a nice coincidence actually :) I reckon it's possible to do this in a really distributed manner (the cloud2device is harder, but again would be a fun challenge to try and replace with something open and distributed)

+Fernando Miguel In this case though, there is a large amount of scrutiny at the moment, and in the future. There's people here with a lot of experience with infosec that I've pointed this to, and who may well comment. There's already suggestions on the issue tracker from people with good experience implementing crypto on mobile.

The difference with crypto is that the algorithms are already out there, and have had the review and scrutiny done well. There are papers and proofs available, which can and have been verified. That's why it's important to never roll your own crypto. By implementing existing algorithms it's possible to make this VERY secure.
I think this is a great idea! What better time to implement this than now. I r excite.
Brilliant idea, and an impressive example of digital darwinism !
so, basically, after I send a SMS from any messaging app, the system will treat it  as a push message and send it to GCM then the receiver will get that push message like a normal SMS.
if the connection is not available then it will be sent like a normal sms?
What if data is disabled ? Is there an easy way for the user to know if the message has been transmitted as legacy SMS, or via GCM ?
Yes, i think it should have a promt if that message will be sent as a normal sms or not
With TextSecure compatibility, the fallback to SMS can still be encrypted, as long as the other party also uses TextSecure. So basically there are three security layers:

-> Both parties using cm pushsms
-> Fallback to TextSecure
-> Fallback to plaintext SMS (optional)

Is this correct?

Also, if I'm using an older version of CM (like CM9) because my phone isn't supported anymore, is it possible to get a flashable zip with the necessary framework, proxy and SMS app?
Ok, it makes sense, thanks. 
TextSecure is SMS only though, from what I understand, I'd prefer an app that uses data, and only revert to sms when out of data coverage. 
Add a comment...