| /*- |
| * Copyright 2014 Square Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package josecipher |
| |
| import ( |
| "crypto" |
| "encoding/binary" |
| "hash" |
| "io" |
| ) |
| |
| type concatKDF struct { |
| z, info []byte |
| i uint32 |
| cache []byte |
| hasher hash.Hash |
| } |
| |
| // NewConcatKDF builds a KDF reader based on the given inputs. |
| func NewConcatKDF(hash crypto.Hash, z, algID, ptyUInfo, ptyVInfo, supPubInfo, supPrivInfo []byte) io.Reader { |
| buffer := make([]byte, uint64(len(algID))+uint64(len(ptyUInfo))+uint64(len(ptyVInfo))+uint64(len(supPubInfo))+uint64(len(supPrivInfo))) |
| n := 0 |
| n += copy(buffer, algID) |
| n += copy(buffer[n:], ptyUInfo) |
| n += copy(buffer[n:], ptyVInfo) |
| n += copy(buffer[n:], supPubInfo) |
| copy(buffer[n:], supPrivInfo) |
| |
| hasher := hash.New() |
| |
| return &concatKDF{ |
| z: z, |
| info: buffer, |
| hasher: hasher, |
| cache: []byte{}, |
| i: 1, |
| } |
| } |
| |
| func (ctx *concatKDF) Read(out []byte) (int, error) { |
| copied := copy(out, ctx.cache) |
| ctx.cache = ctx.cache[copied:] |
| |
| for copied < len(out) { |
| ctx.hasher.Reset() |
| |
| // Write on a hash.Hash never fails |
| _ = binary.Write(ctx.hasher, binary.BigEndian, ctx.i) |
| _, _ = ctx.hasher.Write(ctx.z) |
| _, _ = ctx.hasher.Write(ctx.info) |
| |
| hash := ctx.hasher.Sum(nil) |
| chunkCopied := copy(out[copied:], hash) |
| copied += chunkCopied |
| ctx.cache = hash[chunkCopied:] |
| |
| ctx.i++ |
| } |
| |
| return copied, nil |
| } |