net.i2p.crypto
Class ElGamalAESEngine

java.lang.Object
  extended by net.i2p.crypto.ElGamalAESEngine

public class ElGamalAESEngine
extends java.lang.Object

Handles the actual ElGamal+AES encryption and decryption scenarios using the supplied keys and data.


Constructor Summary
ElGamalAESEngine(I2PAppContext ctx)
           
 
Method Summary
 byte[] decrypt(byte[] data, PrivateKey targetPrivateKey)
          Deprecated. specify the key manager!
 byte[] decrypt(byte[] data, PrivateKey targetPrivateKey, SessionKeyManager keyManager)
          Decrypt the message using the given private key and using tags from the specified key manager.
(package private)  byte[] decryptAESBlock(byte[] encrypted, int offset, int encryptedLen, SessionKey key, byte[] iv, byte[] sentTag, java.util.Set foundTags, SessionKey foundKey)
           
(package private)  byte[] decryptAESBlock(byte[] encrypted, SessionKey key, byte[] iv, byte[] sentTag, java.util.Set foundTags, SessionKey foundKey)
          Decrypt the AES data with the session key and IV.
(package private)  byte[] decryptExistingSession(byte[] data, SessionKey key, PrivateKey targetPrivateKey, java.util.Set foundTags, SessionKey usedKey, SessionKey foundKey)
          scenario 2: The data begins with 32 byte session tag, which also serves as the preIV.
(package private)  byte[] decryptNewSession(byte[] data, PrivateKey targetPrivateKey, java.util.Set foundTags, SessionKey usedKey, SessionKey foundKey)
          scenario 1: Begin with 222 bytes, ElG encrypted, containing: - 32 byte SessionKey - 32 byte pre-IV for the AES - 158 bytes of random padding After encryption, the ElG section is 514 bytes long.
 byte[] encrypt(byte[] data, PublicKey target, SessionKey key, long paddedSize)
          Deprecated. unused
 byte[] encrypt(byte[] data, PublicKey target, SessionKey key, java.util.Set tagsForDelivery, long paddedSize)
          Deprecated. unused
 byte[] encrypt(byte[] data, PublicKey target, SessionKey key, java.util.Set tagsForDelivery, SessionTag currentTag, long paddedSize)
          Encrypt the data to the target using the given key and deliver the specified tags No new session key This is the one called from GarlicMessageBuilder and is the primary entry point.
 byte[] encrypt(byte[] data, PublicKey target, SessionKey key, java.util.Set tagsForDelivery, SessionTag currentTag, SessionKey newKey, long paddedSize)
          Encrypt the unencrypted data to the target.
(package private)  byte[] encryptAESBlock(byte[] data, SessionKey key, byte[] iv, java.util.Set tagsForDelivery, SessionKey newKey, long paddedSize)
          For both scenarios, this method encrypts the AES area using the given key, iv and making sure the resulting data is at least as long as the paddedSize and also mod 16 bytes.
(package private)  byte[] encryptAESBlock(byte[] data, SessionKey key, byte[] iv, java.util.Set tagsForDelivery, SessionKey newKey, long paddedSize, int prefixBytes)
           
(package private)  byte[] encryptExistingSession(byte[] data, PublicKey target, SessionKey key, java.util.Set tagsForDelivery, SessionTag currentTag, SessionKey newKey, long paddedSize)
          scenario 2: Begin with 32 byte session tag, which also serves as the preIV.
(package private)  byte[] encryptNewSession(byte[] data, PublicKey target, SessionKey key, java.util.Set tagsForDelivery, SessionKey newKey, long paddedSize)
          scenario 1: Begin with 222 bytes, ElG encrypted, containing: - 32 byte SessionKey - 32 byte pre-IV for the AES - 158 bytes of random padding After encryption, the ElG section is 514 bytes long.
(package private) static byte[] getPadding(I2PAppContext context, int curSize, long minPaddedSize)
          Return random bytes for padding the data to a mod 16 size so that it is at least minPaddedSize
(package private) static int getPaddingSize(int curSize, long minPaddedSize)
           
static void main(java.lang.String[] args)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

ElGamalAESEngine

public ElGamalAESEngine(I2PAppContext ctx)
Method Detail

decrypt

public byte[] decrypt(byte[] data,
                      PrivateKey targetPrivateKey)
               throws DataFormatException
Deprecated. specify the key manager!

Decrypt the message using the given private key using tags from the default key manager.

Throws:
DataFormatException

decrypt

public byte[] decrypt(byte[] data,
                      PrivateKey targetPrivateKey,
                      SessionKeyManager keyManager)
               throws DataFormatException
Decrypt the message using the given private key and using tags from the specified key manager. This works according to the ElGamal+AES algorithm in the data structure spec.

Returns:
decrypted data or null on failure
Throws:
DataFormatException

decryptNewSession

byte[] decryptNewSession(byte[] data,
                         PrivateKey targetPrivateKey,
                         java.util.Set foundTags,
                         SessionKey usedKey,
                         SessionKey foundKey)
                   throws DataFormatException
scenario 1: Begin with 222 bytes, ElG encrypted, containing:
  - 32 byte SessionKey
  - 32 byte pre-IV for the AES
  - 158 bytes of random padding
 
After encryption, the ElG section is 514 bytes long. Then encrypt with AES using that session key and the first 16 bytes of the SHA256 of the pre-IV, using the decryptAESBlock method & structure.

Parameters:
foundTags - set which is filled with any sessionTags found during decryption
foundKey - session key which may be filled with a new sessionKey found during decryption
Returns:
null if decryption fails
Throws:
DataFormatException

decryptExistingSession

byte[] decryptExistingSession(byte[] data,
                              SessionKey key,
                              PrivateKey targetPrivateKey,
                              java.util.Set foundTags,
                              SessionKey usedKey,
                              SessionKey foundKey)
                        throws DataFormatException
scenario 2: The data begins with 32 byte session tag, which also serves as the preIV. Then decrypt with AES using that session key and the first 16 bytes of the SHA256 of the pre-IV:
  - 2 byte integer specifying the # of session tags
  - that many 32 byte session tags
  - 4 byte integer specifying data.length
  - SHA256 of data
  - 1 byte flag that, if == 1, is followed by a new SessionKey
  - data
  - random bytes, padding the total size to greater than paddedSize with a mod 16 = 0
 
If anything doesn't match up in decryption, it falls back to decryptNewSession

Parameters:
foundTags - set which is filled with any sessionTags found during decryption
foundKey - session key which may be filled with a new sessionKey found during decryption
Returns:
decrypted data or null on failure
Throws:
DataFormatException

decryptAESBlock

byte[] decryptAESBlock(byte[] encrypted,
                       SessionKey key,
                       byte[] iv,
                       byte[] sentTag,
                       java.util.Set foundTags,
                       SessionKey foundKey)
                 throws DataFormatException
Decrypt the AES data with the session key and IV. The result should be:
  - 2 byte integer specifying the # of session tags
  - that many 32 byte session tags
  - 4 byte integer specifying data.length
  - SHA256 of data
  - 1 byte flag that, if == 1, is followed by a new SessionKey
  - data
  - random bytes, padding the total size to greater than paddedSize with a mod 16 = 0
 
If anything doesn't match up in decryption, return null. Otherwise, return the decrypted data and update the session as necessary. If the sentTag is not null, consume it, but if it is null, record the keys, etc as part of a new session.

Parameters:
foundTags - set which is filled with any sessionTags found during decryption
foundKey - session key which may be filled with a new sessionKey found during decryption
Returns:
decrypted data or null on failure
Throws:
DataFormatException

decryptAESBlock

byte[] decryptAESBlock(byte[] encrypted,
                       int offset,
                       int encryptedLen,
                       SessionKey key,
                       byte[] iv,
                       byte[] sentTag,
                       java.util.Set foundTags,
                       SessionKey foundKey)
                 throws DataFormatException
Throws:
DataFormatException

encrypt

public byte[] encrypt(byte[] data,
                      PublicKey target,
                      SessionKey key,
                      java.util.Set tagsForDelivery,
                      SessionTag currentTag,
                      SessionKey newKey,
                      long paddedSize)
Encrypt the unencrypted data to the target. The total size returned will be no less than the paddedSize parameter, but may be more. This method uses the ElGamal+AES algorithm in the data structure spec.

Parameters:
target - public key to which the data should be encrypted.
key - session key to use during encryption
tagsForDelivery - session tags to be associated with the key (or newKey if specified), or null
currentTag - sessionTag to use, or null if it should use ElG (i.e. new session)
newKey - key to be delivered to the target, with which the tagsForDelivery should be associated, or null
paddedSize - minimum size in bytes of the body after padding it (if less than the body's real size, no bytes are appended but the body is not truncated) Unused externally, only called by below (i.e. newKey is always null)

encrypt

public byte[] encrypt(byte[] data,
                      PublicKey target,
                      SessionKey key,
                      java.util.Set tagsForDelivery,
                      SessionTag currentTag,
                      long paddedSize)
Encrypt the data to the target using the given key and deliver the specified tags No new session key This is the one called from GarlicMessageBuilder and is the primary entry point.


encrypt

public byte[] encrypt(byte[] data,
                      PublicKey target,
                      SessionKey key,
                      java.util.Set tagsForDelivery,
                      long paddedSize)
Deprecated. unused

Encrypt the data to the target using the given key and deliver the specified tags No new session key No current tag (encrypt as new session)


encrypt

public byte[] encrypt(byte[] data,
                      PublicKey target,
                      SessionKey key,
                      long paddedSize)
Deprecated. unused

Encrypt the data to the target using the given key delivering no tags No new session key No current tag (encrypt as new session)


encryptNewSession

byte[] encryptNewSession(byte[] data,
                         PublicKey target,
                         SessionKey key,
                         java.util.Set tagsForDelivery,
                         SessionKey newKey,
                         long paddedSize)
scenario 1: Begin with 222 bytes, ElG encrypted, containing:
  - 32 byte SessionKey
  - 32 byte pre-IV for the AES
  - 158 bytes of random padding
 
After encryption, the ElG section is 514 bytes long. Then encrypt the following with AES using that session key and the first 16 bytes of the SHA256 of the pre-IV:
  - 2 byte integer specifying the # of session tags
  - that many 32 byte session tags
  - 4 byte integer specifying data.length
  - SHA256 of data
  - 1 byte flag that, if == 1, is followed by a new SessionKey
  - data
  - random bytes, padding the total size to greater than paddedSize with a mod 16 = 0
 


encryptExistingSession

byte[] encryptExistingSession(byte[] data,
                              PublicKey target,
                              SessionKey key,
                              java.util.Set tagsForDelivery,
                              SessionTag currentTag,
                              SessionKey newKey,
                              long paddedSize)
scenario 2: Begin with 32 byte session tag, which also serves as the preIV. Then encrypt with AES using that session key and the first 16 bytes of the SHA256 of the pre-IV:
  - 2 byte integer specifying the # of session tags
  - that many 32 byte session tags
  - 4 byte integer specifying data.length
  - SHA256 of data
  - 1 byte flag that, if == 1, is followed by a new SessionKey
  - data
  - random bytes, padding the total size to greater than paddedSize with a mod 16 = 0
 


encryptAESBlock

final byte[] encryptAESBlock(byte[] data,
                             SessionKey key,
                             byte[] iv,
                             java.util.Set tagsForDelivery,
                             SessionKey newKey,
                             long paddedSize)
For both scenarios, this method encrypts the AES area using the given key, iv and making sure the resulting data is at least as long as the paddedSize and also mod 16 bytes. The contents of the encrypted data is:
  - 2 byte integer specifying the # of session tags
  - that many 32 byte session tags
  - 4 byte integer specifying data.length
  - SHA256 of data
  - 1 byte flag that, if == 1, is followed by a new SessionKey
  - data
  - random bytes, padding the total size to greater than paddedSize with a mod 16 = 0
 


encryptAESBlock

final byte[] encryptAESBlock(byte[] data,
                             SessionKey key,
                             byte[] iv,
                             java.util.Set tagsForDelivery,
                             SessionKey newKey,
                             long paddedSize,
                             int prefixBytes)

getPadding

static final byte[] getPadding(I2PAppContext context,
                               int curSize,
                               long minPaddedSize)
Return random bytes for padding the data to a mod 16 size so that it is at least minPaddedSize


getPaddingSize

static final int getPaddingSize(int curSize,
                                long minPaddedSize)

main

public static void main(java.lang.String[] args)