blob: 38dce949a2776e46e1495a5448b5ca98ec4efbe9 [file] [log] [blame]
// 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.
//
////////////////////////////////////////////////////////////////////////////////
goog.module('tink.subtle.purejs.Hmac');
const Bytes = goog.require('tink.subtle.Bytes');
const GoogHmac = goog.require('goog.crypt.Hmac');
const InvalidArgumentsException = goog.require('tink.exception.InvalidArgumentsException');
const Mac = goog.require('tink.Mac');
const Sha1 = goog.require('goog.crypt.Sha1');
const Sha256 = goog.require('goog.crypt.Sha256');
const Sha512 = goog.require('goog.crypt.Sha512');
const Validators = goog.require('tink.subtle.Validators');
/**
* Implementation of HMAC.
*
* @implements {Mac}
* @public
* @final
*/
class Hmac {
/**
* @param {string} hash name of the hash function, accepted names are SHA-1,
* SHA-256 and SHA-512
* @param {!Uint8Array} key
* @param {number} tagSize the size of the tag
*/
constructor(hash, key, tagSize) {
/** @const @private {number} */
this.tagSize_ = tagSize;
/** @private {GoogHmac} */
this.hmac_;
switch (hash) {
case 'SHA-1':
this.hmac_ = new GoogHmac(new Sha1(), Array.from(key));
break;
case 'SHA-256':
this.hmac_ = new GoogHmac(new Sha256(), Array.from(key));
break;
case 'SHA-512':
this.hmac_ = new GoogHmac(new Sha512(), Array.from(key));
break;
default:
throw new InvalidArgumentsException(hash + ' is not supported');
}
}
/**
* @override
*/
async computeMac(data) {
Validators.requireUint8Array(data);
const tag = this.hmac_.getHmac(data);
return new Uint8Array(tag.slice(0, this.tagSize_));
}
/**
* @override
*/
async verifyMac(tag, data) {
Validators.requireUint8Array(tag);
Validators.requireUint8Array(data);
const computedTag = await this.computeMac(data);
return Bytes.isEqual(tag, computedTag);
}
}
exports = Hmac;