Search in sources :

Example 1 with SessionKey

use of net.i2p.data.SessionKey in project i2p.i2p by i2p.

the class ElGamalAESEngine method decryptAESBlock.

/**
 * Decrypt the AES data with the session key and IV.  The result should be:
 * <pre>
 *  - 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
 * </pre>
 *
 * 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.
 *
 * @param foundTags set which is filled with any sessionTags found during decryption
 * @param foundKey  out parameter. Data must be unset when called; may be filled with a new sessionKey found during decryption
 * @return decrypted data or null on failure
 */
/**
 **
 *    private byte[] decryptAESBlock(byte encrypted[], SessionKey key, byte iv[],
 *                           byte sentTag[], Set foundTags, SessionKey foundKey) throws DataFormatException {
 *        return decryptAESBlock(encrypted, 0, encrypted.length, key, iv, sentTag, foundTags, foundKey);
 *    }
 ***
 */
/*
     * Note: package private for ElGamalTest.testAES()
     */
byte[] decryptAESBlock(byte[] encrypted, int offset, int encryptedLen, SessionKey key, byte[] iv, byte[] sentTag, Set<SessionTag> foundTags, SessionKey foundKey) throws DataFormatException {
    // _log.debug("iv for decryption: " + DataHelper.toString(iv, 16));
    // _log.debug("decrypting AES block.  encr.length = " + (encrypted == null? -1 : encrypted.length) + " sentTag: " + DataHelper.toString(sentTag, 32));
    byte[] decrypted = new byte[encryptedLen];
    _context.aes().decrypt(encrypted, offset, decrypted, 0, key, iv, encryptedLen);
    // _log.debug("Hash of entire aes block after decryption: \n" + DataHelper.toString(h.getData(), 32));
    try {
        SessionKey newKey = null;
        List<SessionTag> tags = null;
        // ByteArrayInputStream bais = new ByteArrayInputStream(decrypted);
        int cur = 0;
        long numTags = DataHelper.fromLong(decrypted, cur, 2);
        if ((numTags < 0) || (numTags > MAX_TAGS_RECEIVED))
            throw new IllegalArgumentException("Invalid number of session tags");
        if (numTags > 0)
            tags = new ArrayList<SessionTag>((int) numTags);
        cur += 2;
        // _log.debug("# tags: " + numTags);
        if (numTags * SessionTag.BYTE_LENGTH > decrypted.length - 2) {
            throw new IllegalArgumentException("# tags: " + numTags + " is too many for " + (decrypted.length - 2));
        }
        for (int i = 0; i < numTags; i++) {
            byte[] tag = new byte[SessionTag.BYTE_LENGTH];
            System.arraycopy(decrypted, cur, tag, 0, SessionTag.BYTE_LENGTH);
            cur += SessionTag.BYTE_LENGTH;
            tags.add(new SessionTag(tag));
        }
        long len = DataHelper.fromLong(decrypted, cur, 4);
        cur += 4;
        // _log.debug("len: " + len);
        if ((len < 0) || (len > decrypted.length - cur - Hash.HASH_LENGTH - 1))
            throw new IllegalArgumentException("Invalid size of payload (" + len + ", remaining " + (decrypted.length - cur) + ")");
        // byte hashval[] = new byte[Hash.HASH_LENGTH];
        // System.arraycopy(decrypted, cur, hashval, 0, Hash.HASH_LENGTH);
        // readHash = new Hash();
        // readHash.setData(hashval);
        // readHash = Hash.create(decrypted, cur);
        int hashIndex = cur;
        cur += Hash.HASH_LENGTH;
        byte flag = decrypted[cur++];
        if (flag == 0x01) {
            byte[] rekeyVal = new byte[SessionKey.KEYSIZE_BYTES];
            System.arraycopy(decrypted, cur, rekeyVal, 0, SessionKey.KEYSIZE_BYTES);
            cur += SessionKey.KEYSIZE_BYTES;
            newKey = new SessionKey();
            newKey.setData(rekeyVal);
        }
        byte[] unencrData = new byte[(int) len];
        System.arraycopy(decrypted, cur, unencrData, 0, (int) len);
        cur += (int) len;
        // use alternate calculateHash() method to avoid object churn and caching
        // Hash calcHash = _context.sha().calculateHash(unencrData);
        // boolean eq = calcHash.equals(readHash);
        byte[] calcHash = SimpleByteCache.acquire(32);
        _context.sha().calculateHash(unencrData, 0, (int) len, calcHash, 0);
        boolean eq = DataHelper.eq(decrypted, hashIndex, calcHash, 0, 32);
        SimpleByteCache.release(calcHash);
        if (eq) {
            // everything matches.  w00t.
            if (tags != null)
                foundTags.addAll(tags);
            if (newKey != null)
                foundKey.setData(newKey.getData());
            return unencrData;
        }
        throw new RuntimeException("Hash does not match");
    } catch (RuntimeException e) {
        if (_log.shouldLog(Log.WARN))
            _log.warn("Unable to decrypt AES block", e);
        return null;
    }
}
Also used : SessionKey(net.i2p.data.SessionKey) ArrayList(java.util.ArrayList) SessionTag(net.i2p.data.SessionTag)

Example 2 with SessionKey

use of net.i2p.data.SessionKey in project i2p.i2p by i2p.

the class KeyGenerator method generateSessionKey.

/**
 *  PBE the passphrase with the salt.
 *  Warning - SLOW
 */
public SessionKey generateSessionKey(byte[] salt, byte[] passphrase) {
    byte[] salted = new byte[16 + passphrase.length];
    System.arraycopy(salt, 0, salted, 0, Math.min(salt.length, 16));
    System.arraycopy(passphrase, 0, salted, 16, passphrase.length);
    byte[] h = _context.sha().calculateHash(salted).getData();
    for (int i = 1; i < PBE_ROUNDS; i++) _context.sha().calculateHash(h, 0, Hash.HASH_LENGTH, h, 0);
    return new SessionKey(h);
}
Also used : SessionKey(net.i2p.data.SessionKey) ECPoint(java.security.spec.ECPoint)

Example 3 with SessionKey

use of net.i2p.data.SessionKey in project i2p.i2p by i2p.

the class AES256Test method testShort.

public void testShort() {
    I2PAppContext ctx = new I2PAppContext();
    SessionKey key = ctx.keyGenerator().generateSessionKey();
    byte[] iv = new byte[16];
    RandomSource.getInstance().nextBytes(iv);
    byte[] sbuf = new byte[16];
    RandomSource.getInstance().nextBytes(sbuf);
    byte[] se = new byte[16];
    ctx.aes().encrypt(sbuf, 0, se, 0, key, iv, sbuf.length);
    byte[] sd = new byte[16];
    ctx.aes().decrypt(se, 0, sd, 0, key, iv, se.length);
    assertTrue(DataHelper.eq(sd, sbuf));
}
Also used : I2PAppContext(net.i2p.I2PAppContext) SessionKey(net.i2p.data.SessionKey)

Example 4 with SessionKey

use of net.i2p.data.SessionKey in project i2p.i2p by i2p.

the class AES256Test method testMultiple.

public void testMultiple() {
    for (int i = 0; i < 100; i++) {
        SessionKey key = _context.keyGenerator().generateSessionKey();
        byte[] iv = new byte[16];
        _context.random().nextBytes(iv);
        byte[] plain = new byte[256];
        _context.random().nextBytes(plain);
        byte[] e = new byte[plain.length];
        _context.aes().encrypt(plain, 0, e, 0, key, iv, plain.length);
        byte[] d = new byte[e.length];
        _context.aes().decrypt(e, 0, d, 0, key, iv, d.length);
        boolean same = true;
        assertTrue(DataHelper.eq(plain, d));
    }
}
Also used : SessionKey(net.i2p.data.SessionKey)

Example 5 with SessionKey

use of net.i2p.data.SessionKey in project i2p.i2p by i2p.

the class CryptixAESEngineTest method testED.

public void testED() {
    I2PAppContext ctx = I2PAppContext.getGlobalContext();
    SessionKey key = ctx.keyGenerator().generateSessionKey();
    byte[] iv = new byte[16];
    byte[] orig = new byte[128];
    byte[] encrypted = new byte[128];
    byte[] decrypted = new byte[128];
    ctx.random().nextBytes(iv);
    ctx.random().nextBytes(orig);
    CryptixAESEngine aes = new CryptixAESEngine(ctx);
    aes.encrypt(orig, 0, encrypted, 0, key, iv, orig.length);
    aes.decrypt(encrypted, 0, decrypted, 0, key, iv, encrypted.length);
    assertTrue(DataHelper.eq(decrypted, orig));
}
Also used : I2PAppContext(net.i2p.I2PAppContext) SessionKey(net.i2p.data.SessionKey)

Aggregations

SessionKey (net.i2p.data.SessionKey)69 SessionTag (net.i2p.data.SessionTag)15 PublicKey (net.i2p.data.PublicKey)14 I2PAppContext (net.i2p.I2PAppContext)13 HashSet (java.util.HashSet)11 Hash (net.i2p.data.Hash)11 SessionKeyManager (net.i2p.crypto.SessionKeyManager)10 PrivateKey (net.i2p.data.PrivateKey)10 InetAddress (java.net.InetAddress)9 DataFormatException (net.i2p.data.DataFormatException)9 UnknownHostException (java.net.UnknownHostException)7 TagSetHandle (net.i2p.crypto.TagSetHandle)5 Map (java.util.Map)4 GarlicMessage (net.i2p.data.i2np.GarlicMessage)4 IOException (java.io.IOException)3 ArrayList (java.util.ArrayList)3 HashMap (java.util.HashMap)3 Set (java.util.Set)3 EncryptedBuildRecord (net.i2p.data.i2np.EncryptedBuildRecord)3 BigInteger (java.math.BigInteger)2