n('Invalid key length', 'DataError');
      }

      keyObject = createSecretKey(keyData);
      break;
    }
    case 'jwk': {
      if (keyData == null || typeof keyData !== 'object')
        throw lazyDOMException('Invalid JWK keyData', 'DataError');

      if (keyData.kty !== 'oct')
        throw lazyDOMException('Invalid key type', 'DataError');

      if (usagesSet.size > 0 &&
          keyData.use !== undefined &&
          keyData.use !== 'sig') {
        throw lazyDOMException('Invalid use type', 'DataError');
      }

      validateKeyOps(keyData.key_ops, usagesSet);

      if (keyData.ext !== undefined &&
          keyData.ext === false &&
          extractable === true) {
        throw lazyDOMException('JWK is not extractable', 'DataError');
      }

      if (keyData.alg !== undefined) {
        if (typeof keyData.alg !== 'string')
          throw lazyDOMException('Invalid alg', 'DataError');
        switch (keyData.alg) {
          case 'HS1':
            if (algorithm.hash.name !== 'SHA-1')
              throw lazyDOMException('Digest algorithm mismatch', 'DataError');
            break;
          case 'HS256':
            if (algorithm.hash.name !== 'SHA-256')
              throw lazyDOMException('Digest algorithm mismatch', 'DataError');
            break;
          case 'HS384':
            if (algorithm.hash.name !== 'SHA-384')
              throw lazyDOMException('Digest algorithm mismatch', 'DataError');
            break;
          case 'HS512':
            if (algorithm.hash.name !== 'SHA-512')
              throw lazyDOMException('Digest algorithm mismatch', 'DataError');
            break;
          default:
            throw lazyDOMException('Unsupported digest algorithm', 'DataError');
        }
      }

      const handle = new KeyObjectHandle();
      handle.initJwk(keyData);
      keyObject = new SecretKeyObject(handle);
      break;
    }
    default:
      throw lazyDOMException(`Unable to import HMAC key with format ${format}`);
  }

  const { length } = keyObject[kHandle].keyDetail({});

  return new InternalCryptoKey(
    keyObject, {
      name: 'HMAC',
      hash: algorithm.hash,
      length,
    },
    keyUsages,
    extractable);
}

function hmacSignVerify(key, data, algorithm, signature) {
  const mode = signature === undefined ? kSignJobModeSign : kSignJobModeVerify;
  return jobPromise(new HmacJob(
    kCryptoJobAsync,
    mode,
    normalizeHashName(key.algorithm.hash.name),
    key[kKeyObject][kHandle],
    data,
    signature));
}

module.exports = {
  hmacImportKey,
  hmacGenerateKey,
  hmacSignVerify,
};
