I am writing an application to generate OTP codes for two factor authentication where I need to securely store data locally. This data must be secure from both the owner/user as well as intruders. I have been thinking of encrypting the data, but the key to that data is also stored on the mobile device. The application will not access the internet. It just displays a code that changes over a given time interval, similar to an RSA SecurID token. The data to be stored is the token key and the key to decrypt it. I have read about possible solutions that it may be possible to store this information on the SIM card or other secure store on the device. What are industry best practices for such a scenario?
The important point is that you cannot hide secrets in software: if some software runs on the hardware owned by the attacker (here, the user and his smartphone), then the attacker can reverse-engineer the application code and extract the secret. If it was possible to protect software from that, then there would be no software or video piracy. Media industry would be very interested; they have looked high and low for a solution, and spent a lot of money on the subject, and did not find anything really robust.
So you need tamper-resistant hardware, i.e. hardware which will prevent reverse-engineering. In a smartphone, this indeed points at the SIM card: smart cards are, by design, tamper-resistant. In fact, the SIM card is the only tamper-resistant piece of hardware that can be found in a typical smartphone, so you have to use it. However, there will be additional challenges:
For proper protection, you must not use the SIM card only as storage; the point of tamper resistance is to never let the key exit the card. If the card just handed the key over to whoever asks for it, the attacker would have no trouble extracting it. So the complete computation must occur within the card. Depending on how programmable the card is, this may or may not be easy; in any case, the card vendor and the phone operator will have to be involved.
There is no clock in a smart card. If the algorithm depends on the current time, then that time must be obtained from the outside, and that "outside" is the phone, under full control of the attacker. The phone may lie. This would allow the attacker to generate the codes for, say, the complete next year. Depending on what you do with the codes, this may or may not be a problem for you; but you have to take that into account in your security model.
The clock issue might be avoided if you generate your codes not with a clock, but with a counter, like what is done with HOTP. A feature of RSA SecurID tokens is indeed that they include an internal battery powered clock that the user cannot tamper with; this is an expensive feature which explains both the size (substantially bigger than a smart card chip) and the price of these tokens.
Another way to avoid the clock issue is to use the network. The code in the smart card would generate a random challenge (say, 16 random bytes), send that to the phone; the phone would then talk to a Time Stamp Authority who would sign the challenge along with the current date and time, and send back the signature. The smart card would still have to verify that signature, and check that the response indeed contains the correct challenge value. This process ensures that the card obtains an untampered-with notion of the current time with decent accuracy. But the protocol has become quite complex, and involves network access (not necessarily easy, especially when the phone owner is in a foreign country) and a trusted server (which has to be maintained).