Ejemplo n.º 1
0
// DeriveConcatKDF implements NIST SP 800-56A Concatenation Key Derivation Function. Derives
// key material of keydatalen bits size given Z (sharedSecret), OtherInfo (AlgorithmID |
// PartyUInfo | PartyVInfo | SuppPubInfo | SuppPrivInfo) and hash function
func DeriveConcatKDF(keydatalen int, sharedSecret, algId, partyUInfo, partyVInfo, suppPubInfo, suppPrivInfo []byte, h hash.Hash) []byte {

	otherInfo := arrays.Concat(algId, partyUInfo, partyVInfo, suppPubInfo, suppPrivInfo)

	keyLenBytes := keydatalen >> 3

	reps := int(math.Ceil(float64(keyLenBytes) / float64(h.Size())))

	if reps > MaxInt {
		panic("kdf.DeriveConcatKDF: too much iterations (more than 2^32-1).")
	}

	dk := make([]byte, 0, keyLenBytes)

	for counter := 1; counter <= reps; counter++ {
		h.Reset()

		counterBytes := arrays.UInt32ToBytes(uint32(counter))

		h.Write(counterBytes)
		h.Write(sharedSecret)
		h.Write(otherInfo)

		dk = h.Sum(dk)
	}

	return dk[:keyLenBytes]
}
Ejemplo n.º 2
0
func (alg *AesCbcHmac) computeAuthTag(aad []byte, iv []byte, cipherText []byte, hmacKey []byte) (signature []byte) {
	al := arrays.UInt64ToBytes(uint64(len(aad) << 3))
	hmacInput := arrays.Concat(aad, iv, cipherText, al)
	hmac := calculateHmac(alg.keySizeBits, hmacInput, hmacKey)

	return hmac[0 : len(hmac)/2]
}
Ejemplo n.º 3
0
func (alg *Pbse2HmacAesKW) Unwrap(encryptedCek []byte, key interface{}, cekSizeBits int, header map[string]interface{}) (cek []byte, err error) {

	if passphrase, ok := key.(string); ok {

		var p2s string
		var p2c float64

		if p2c, ok = header["p2c"].(float64); !ok {
			return nil, errors.New("Pbse2HmacAesKW.Unwrap(): expected 'p2c' param in JWT header, but was not found.")
		}

		if p2s, ok = header["p2s"].(string); !ok {
			return nil, errors.New("Pbse2HmacAesKW.Unwrap(): expected 'p2s' param in JWT header, but was not found.")
		}

		var saltInput []byte

		algId := []byte(header["alg"].(string))

		if saltInput, err = base64url.Decode(p2s); err != nil {
			return nil, err
		}

		salt := arrays.Concat(algId, []byte{0}, saltInput)

		kek := kdf.DerivePBKDF2([]byte(passphrase), salt, int(p2c), alg.keySizeBits, alg.prf())

		return alg.aesKW.Unwrap(encryptedCek, kek, cekSizeBits, header)
	}

	return nil, errors.New("Pbse2HmacAesKW.Unwrap(): expected key to be 'string' array")
}
Ejemplo n.º 4
0
// KeyWrap encrypts provided key (CEK) with KEK key using AES Key Wrap (rfc 3394) algorithm
func KeyWrap(cek, kek []byte) ([]byte, error) {
	// 1) Initialize variables
	a := defaultIV            // Set A = IV, an initial value
	r := arrays.Slice(cek, 8) // For i = 1 to n
	//     R[0][i] = P[i]
	n := uint64(len(r))

	// 2) Calculate intermediate values.
	var j, i, t uint64

	for j = 0; j < 6; j++ { // For j = 0 to 5
		for i = 0; i < n; i++ { //    For i=1 to n
			t = n*j + i + 1
			b, e := aesEnc(kek, arrays.Concat(a, r[i])) //       B=AES(K, A | R[i])

			if e != nil {
				return nil, e
			}

			a = b[:len(b)/2]    //       A=MSB(64,B) ^ t where t = (n*j)+i
			r[i] = b[len(b)/2:] //       R[i] = LSB(64, B)
			a = arrays.Xor(a, arrays.UInt64ToBytes(t))
		}
	}

	// 3) Output the results
	c := make([][]byte, n+1, n+1)
	c[0] = a                 //  Set C[0] = A
	for i = 1; i <= n; i++ { //  For i = 1 to n
		c[i] = r[i-1] //     C[i] = R[i]
	}

	return arrays.Unwrap(c), nil
}
Ejemplo n.º 5
0
// KeyUnwrap decrypts previously encrypted key (CEK) with KEK key using AES Key Wrap (rfc 3394) algorithm
func KeyUnwrap(encryptedCek, kek []byte) ([]byte, error) {
	// 1) Initialize variables
	c := arrays.Slice(encryptedCek, 8)
	a := c[0] //   Set A = C[0]
	r := make([][]byte, len(c)-1)

	for i := 1; i < len(c); i++ { //   For i = 1 to n
		r[i-1] = c[i] //       R[i] = C[i]
	}

	n := uint64(len(r))

	// 2) Calculate intermediate values
	var t, j uint64

	for j = 6; j > 0; j-- { // For j = 5 to 0
		for i := n; i > 0; i-- { //   For i = n to 1
			t = n*(j-1) + i
			a = arrays.Xor(a, arrays.UInt64ToBytes(t))
			b, e := aesDec(kek, arrays.Concat(a, r[i-1])) //     B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i

			if e != nil {
				return nil, e
			}

			a = b[:len(b)/2]      //     A = MSB(64, B)
			r[i-1] = b[len(b)/2:] //     R[i] = LSB(64, B)
		}
	}

	// 3) Output the results
	if !hmac.Equal(defaultIV, a) { // If A is an appropriate initial value
		return nil, errors.New("aes.KeyUnwrap(): integrity check failed.")
	}

	// For i = 1 to n
	return arrays.Unwrap(r), nil //    P[i] = R[i]

}
Ejemplo n.º 6
0
func (alg *EcdsaUsingSha) Sign(securedInput []byte, key interface{}) (signature []byte, err error) {

	if privKey, ok := key.(*ecdsa.PrivateKey); ok {

		if sizeBits := privKey.Curve.Params().BitSize; sizeBits != alg.keySizeBits {
			return nil, errors.New(fmt.Sprintf("EcdsaUsingSha.Sign(): expected key of size %v bits, but was given %v bits.", alg.keySizeBits, sizeBits))
		}

		var r, s *big.Int

		if r, s, err = ecdsa.Sign(rand.Reader, privKey, sha(alg.hashSizeBits, securedInput)); err == nil {

			rBytes := padding.Align(r.Bytes(), alg.keySizeBits)
			sBytes := padding.Align(s.Bytes(), alg.keySizeBits)

			return arrays.Concat(rBytes, sBytes), nil
		}

		return nil, err
	}

	return nil, errors.New("EcdsaUsingSha.Sign(): expects key to be '*ecdsa.PrivateKey'")
}
Ejemplo n.º 7
0
func (alg *Pbse2HmacAesKW) WrapNewKey(cekSizeBits int, key interface{}, header map[string]interface{}) (cek []byte, encryptedCek []byte, err error) {
	if passphrase, ok := key.(string); ok {

		algId := []byte(header["alg"].(string))

		iterationCount := 8192
		var saltInput []byte

		if saltInput, err = arrays.Random(12); err != nil {
			return nil, nil, err
		}

		header["p2c"] = iterationCount
		header["p2s"] = base64url.Encode(saltInput)

		salt := arrays.Concat(algId, []byte{0}, saltInput)

		kek := kdf.DerivePBKDF2([]byte(passphrase), salt, iterationCount, alg.keySizeBits, alg.prf())
		return alg.aesKW.WrapNewKey(cekSizeBits, kek, header)
	}

	return nil, nil, errors.New("Pbse2HmacAesKW.WrapNewKey(): expected key to be 'string' array")
}
Ejemplo n.º 8
0
func prependDatalen(bytes []byte) []byte {
	return arrays.Concat(arrays.UInt32ToBytes(uint32(len(bytes))), bytes)
}