// 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 }
// 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] }