Пример #1
0
 /**
  * Reseeds this random object. The given seed supplements, rather than replaces, the existing
  * seed. Thus, repeated calls are guaranteed never to reduce randomness.
  *
  * @param seed the seed.
  */
 @Override
 public synchronized void engineSetSeed(byte[] seed) {
   if (state != null) {
     digest.update(state);
     for (int i = 0; i < state.length; i++) {
       state[i] = 0;
     }
   }
   state = digest.digest(seed);
 }
Пример #2
0
  /**
   * Generates a user-specified number of random bytes.
   *
   * @param bytes the array to be filled in with random bytes.
   */
  @Override
  public synchronized void engineNextBytes(byte[] result) {
    int index = 0;
    int todo;
    byte[] output = remainder;

    if (state == null) {
      byte[] seed = new byte[DIGEST_SIZE];
      SeederHolder.seeder.engineNextBytes(seed);
      state = digest.digest(seed);
    }

    // Use remainder from last time
    int r = remCount;
    if (r > 0) {
      // How many bytes?
      todo =
          (result.length - index) < (DIGEST_SIZE - r) ? (result.length - index) : (DIGEST_SIZE - r);
      // Copy the bytes, zero the buffer
      for (int i = 0; i < todo; i++) {
        result[i] = output[r];
        output[r++] = 0;
      }
      remCount += todo;
      index += todo;
    }

    // If we need more bytes, make them.
    while (index < result.length) {
      // Step the state
      digest.update(state);
      output = digest.digest();
      updateState(state, output);

      // How many bytes?
      todo = (result.length - index) > DIGEST_SIZE ? DIGEST_SIZE : result.length - index;
      // Copy the bytes, zero the buffer
      for (int i = 0; i < todo; i++) {
        result[index++] = output[i];
        output[i] = 0;
      }
      remCount += todo;
    }

    // Store remainder for next time
    remainder = output;
    remCount %= DIGEST_SIZE;
  }
Пример #3
0
  /**
   * This call, used by the constructors, instantiates the SHA digest and sets the seed, if given.
   */
  private void init(byte[] seed) {
    try {
      digest = MessageDigest.getInstance("SHA");
    } catch (NoSuchAlgorithmException e) {
      throw new InternalError("internal error: SHA-1 not available.", e);
    }

    if (seed != null) {
      engineSetSeed(seed);
    }
  }
Пример #4
0
  /*
   * readObject is called to restore the state of the random object from
   * a stream.  We have to create a new instance of MessageDigest, because
   * it is not included in the stream (it is marked "transient").
   *
   * Note that the engineNextBytes() method invoked on the restored random
   * object will yield the exact same (random) bytes as the original.
   * If you do not want this behaviour, you should re-seed the restored
   * random object, using engineSetSeed().
   */
  private void readObject(j86.java.io.ObjectInputStream s)
      throws IOException, ClassNotFoundException {

    s.defaultReadObject();

    try {
      digest = MessageDigest.getInstance("SHA");
    } catch (NoSuchAlgorithmException e) {
      throw new InternalError("internal error: SHA-1 not available.", e);
    }
  }
Пример #5
0
  /**
   * Verifies the validity of checksum field
   *
   * @param data the application data
   * @param offset the offset where the data begins
   * @param len the length of the application data
   * @throws GSSException if an error occurs in the checksum calculation
   */
  public final boolean verifySign(byte[] data, int offset, int len) throws GSSException {

    // debug("\t====In verifySign:====\n");
    // debug("\t\t checksum:   [" + getHexBytes(checksum) + "]\n");
    // debug("\t\t data = [" + getHexBytes(data) + "]\n");

    byte[] myChecksum = getChecksum(data, offset, len);
    // debug("\t\t mychecksum: [" + getHexBytes(myChecksum) +"]\n");

    if (MessageDigest.isEqual(checksum, myChecksum)) {
      // debug("\t\t====Checksum PASS:====\n");
      return true;
    }
    return false;
  }
Пример #6
0
 static byte[] doTLS12PRF(
     byte[] secret,
     byte[] labelBytes,
     byte[] seed,
     int outputLength,
     String prfHash,
     int prfHashLength,
     int prfBlockSize)
     throws NoSuchAlgorithmException, DigestException {
   if (prfHash == null) {
     throw new NoSuchAlgorithmException("Unspecified PRF algorithm");
   }
   MessageDigest prfMD = MessageDigest.getInstance(prfHash);
   return doTLS12PRF(secret, labelBytes, seed, outputLength, prfMD, prfHashLength, prfBlockSize);
 }
Пример #7
0
  static byte[] doTLS12PRF(
      byte[] secret,
      byte[] labelBytes,
      byte[] seed,
      int outputLength,
      MessageDigest mdPRF,
      int mdPRFLen,
      int mdPRFBlockSize)
      throws DigestException {

    if (secret == null) {
      secret = B0;
    }

    // If we have a long secret, digest it first.
    if (secret.length > mdPRFBlockSize) {
      secret = mdPRF.digest(secret);
    }

    byte[] output = new byte[outputLength];
    byte[] ipad;
    byte[] opad;

    switch (mdPRFBlockSize) {
      case 64:
        ipad = HMAC_ipad64.clone();
        opad = HMAC_opad64.clone();
        break;
      case 128:
        ipad = HMAC_ipad128.clone();
        opad = HMAC_opad128.clone();
        break;
      default:
        throw new DigestException("Unexpected block size.");
    }

    // P_HASH(Secret, label + seed)
    expand(mdPRF, mdPRFLen, secret, 0, secret.length, labelBytes, seed, output, ipad, opad);

    return output;
  }
Пример #8
0
  /*
   * @param digest the MessageDigest to produce the HMAC
   * @param hmacSize the HMAC size
   * @param secret the secret
   * @param secOff the offset into the secret
   * @param secLen the secret length
   * @param label the label
   * @param seed the seed
   * @param output the output array
   */
  private static void expand(
      MessageDigest digest,
      int hmacSize,
      byte[] secret,
      int secOff,
      int secLen,
      byte[] label,
      byte[] seed,
      byte[] output,
      byte[] pad1,
      byte[] pad2)
      throws DigestException {
    /*
     * modify the padding used, by XORing the key into our copy of that
     * padding.  That's to avoid doing that for each HMAC computation.
     */
    for (int i = 0; i < secLen; i++) {
      pad1[i] ^= secret[i + secOff];
      pad2[i] ^= secret[i + secOff];
    }

    byte[] tmp = new byte[hmacSize];
    byte[] aBytes = null;

    /*
     * compute:
     *
     *     P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
     *                            HMAC_hash(secret, A(2) + seed) +
     *                            HMAC_hash(secret, A(3) + seed) + ...
     * A() is defined as:
     *
     *     A(0) = seed
     *     A(i) = HMAC_hash(secret, A(i-1))
     */
    int remaining = output.length;
    int ofs = 0;
    while (remaining > 0) {
      /*
       * compute A() ...
       */
      // inner digest
      digest.update(pad1);
      if (aBytes == null) {
        digest.update(label);
        digest.update(seed);
      } else {
        digest.update(aBytes);
      }
      digest.digest(tmp, 0, hmacSize);

      // outer digest
      digest.update(pad2);
      digest.update(tmp);
      if (aBytes == null) {
        aBytes = new byte[hmacSize];
      }
      digest.digest(aBytes, 0, hmacSize);

      /*
       * compute HMAC_hash() ...
       */
      // inner digest
      digest.update(pad1);
      digest.update(aBytes);
      digest.update(label);
      digest.update(seed);
      digest.digest(tmp, 0, hmacSize);

      // outer digest
      digest.update(pad2);
      digest.update(tmp);
      digest.digest(tmp, 0, hmacSize);

      int k = Math.min(hmacSize, remaining);
      for (int i = 0; i < k; i++) {
        output[ofs++] ^= tmp[i];
      }
      remaining -= k;
    }
  }
Пример #9
0
  static byte[] doTLS10PRF(
      byte[] secret,
      byte[] labelBytes,
      byte[] seed,
      int outputLength,
      MessageDigest md5,
      MessageDigest sha)
      throws DigestException {
    /*
     * Split the secret into two halves S1 and S2 of same length.
     * S1 is taken from the first half of the secret, S2 from the
     * second half.
     * Their length is created by rounding up the length of the
     * overall secret divided by two; thus, if the original secret
     * is an odd number of bytes long, the last byte of S1 will be
     * the same as the first byte of S2.
     *
     * Note: Instead of creating S1 and S2, we determine the offset into
     * the overall secret where S2 starts.
     */

    if (secret == null) {
      secret = B0;
    }
    int off = secret.length >> 1;
    int seclen = off + (secret.length & 1);

    byte[] secKey = secret;
    int keyLen = seclen;
    byte[] output = new byte[outputLength];

    // P_MD5(S1, label + seed)
    // If we have a long secret, digest it first.
    if (seclen > 64) { // 64: block size of HMAC-MD5
      md5.update(secret, 0, seclen);
      secKey = md5.digest();
      keyLen = secKey.length;
    }
    expand(
        md5,
        16,
        secKey,
        0,
        keyLen,
        labelBytes,
        seed,
        output,
        HMAC_ipad64.clone(),
        HMAC_opad64.clone());

    // P_SHA-1(S2, label + seed)
    // If we have a long secret, digest it first.
    if (seclen > 64) { // 64: block size of HMAC-SHA1
      sha.update(secret, off, seclen);
      secKey = sha.digest();
      keyLen = secKey.length;
      off = 0;
    }
    expand(
        sha,
        20,
        secKey,
        off,
        keyLen,
        labelBytes,
        seed,
        output,
        HMAC_ipad64.clone(),
        HMAC_opad64.clone());

    return output;
  }
Пример #10
0
 static byte[] doTLS10PRF(byte[] secret, byte[] labelBytes, byte[] seed, int outputLength)
     throws NoSuchAlgorithmException, DigestException {
   MessageDigest md5 = MessageDigest.getInstance("MD5");
   MessageDigest sha = MessageDigest.getInstance("SHA1");
   return doTLS10PRF(secret, labelBytes, seed, outputLength, md5, sha);
 }