diff --git a/src/crypto/gcm.js b/src/crypto/gcm.js
index 29a927ea..feccb104 100644
--- a/src/crypto/gcm.js
+++ b/src/crypto/gcm.js
@@ -23,12 +23,14 @@
 'use strict';
 
 import util from '../util.js';
+import config from '../config';
 import asmCrypto from 'asmcrypto-lite';
 const webCrypto = util.getWebCrypto();
 const nodeCrypto = util.getNodeCrypto();
 const Buffer = util.getNodeBuffer();
 
 export const ivLength = 12;
+const ALGO = 'AES-GCM';
 
 /**
  * Encrypt plaintext input.
@@ -40,26 +42,18 @@ export const ivLength = 12;
  */
 export function encrypt(cipher, plaintext, key, iv) {
   if (cipher.substr(0,3) !== 'aes') {
-    return Promise.reject(new Error('Invalid cipher for GCM mode'));
+    return Promise.reject(new Error('GCM mode supports only AES cipher'));
   }
 
-  if (webCrypto) { // native WebCrypto api
-    const keyOptions = {
-      name: 'AES-GCM'
-    },
-    encryptOptions = {
-      name: 'AES-GCM',
-      iv: iv
-    };
-    return webCrypto.importKey('raw', key, keyOptions, false, ['encrypt']).then(keyObj => {
-      return webCrypto.encrypt(encryptOptions, keyObj, plaintext);
-    }).then(ciphertext => {
-      return new Uint8Array(ciphertext);
-    });
+  const keySize = cipher.substr(3,3);
+  if (webCrypto && config.useNative && keySize !== '192') { // WebCrypto (no 192 bit support) see: https://www.chromium.org/blink/webcrypto#TOC-AES-support
+    return webCrypto.importKey('raw', key, { name: ALGO }, false, ['encrypt'])
+      .then(keyObj => webCrypto.encrypt({ name: ALGO, iv }, keyObj, plaintext))
+      .then(ciphertext => new Uint8Array(ciphertext));
 
-  } else if(nodeCrypto) { // native node crypto library
-    let cipherObj = new nodeCrypto.createCipheriv('aes-' + cipher.substr(3,3) + '-gcm', new Buffer(key), new Buffer(iv));
-    let encrypted = Buffer.concat([cipherObj.update(new Buffer(plaintext)), cipherObj.final()]);
+  } else if (nodeCrypto && config.useNative) { // Node crypto library
+    const en = new nodeCrypto.createCipheriv('aes-' + keySize + '-gcm', new Buffer(key), new Buffer(iv));
+    const encrypted = Buffer.concat([en.update(new Buffer(plaintext)), en.final()]);
     return Promise.resolve(new Uint8Array(encrypted));
 
   } else { // asm.js fallback
@@ -77,26 +71,18 @@ export function encrypt(cipher, plaintext, key, iv) {
  */
 export function decrypt(cipher, ciphertext, key, iv) {
   if (cipher.substr(0,3) !== 'aes') {
-    return Promise.reject(new Error('Invalid cipher for GCM mode'));
+    return Promise.reject(new Error('GCM mode supports only AES cipher'));
   }
 
-  if (webCrypto) { // native WebCrypto api
-    const keyOptions = {
-      name: 'AES-GCM'
-    },
-    decryptOptions = {
-      name: 'AES-GCM',
-      iv: iv
-    };
-    return webCrypto.importKey('raw', key, keyOptions, false, ['decrypt']).then(keyObj => {
-      return webCrypto.decrypt(decryptOptions, keyObj, ciphertext);
-    }).then(plaintext => {
-      return new Uint8Array(plaintext);
-    });
+  const keySize = cipher.substr(3,3);
+  if (webCrypto && config.useNative && keySize !== '192') { // WebCrypto (no 192 bit support) see: https://www.chromium.org/blink/webcrypto#TOC-AES-support
+    return webCrypto.importKey('raw', key, { name: ALGO }, false, ['decrypt'])
+      .then(keyObj => webCrypto.decrypt({ name: ALGO, iv }, keyObj, ciphertext))
+      .then(plaintext => new Uint8Array(plaintext));
 
-  } else if(nodeCrypto) { // native node crypto library
-    let decipherObj = new nodeCrypto.createDecipheriv('aes-' + cipher.substr(3,3) + '-gcm', new Buffer(key), new Buffer(iv));
-    let decrypted = Buffer.concat([decipherObj.update(new Buffer(ciphertext)), decipherObj.final()]);
+  } else if (nodeCrypto && config.useNative) { // Node crypto library
+    let de = new nodeCrypto.createDecipheriv('aes-' + keySize + '-gcm', new Buffer(key), new Buffer(iv));
+    let decrypted = Buffer.concat([de.update(new Buffer(ciphertext)), de.final()]);
     return Promise.resolve(new Uint8Array(decrypted));
 
   } else { // asm.js fallback
diff --git a/test/crypto/crypto.js b/test/crypto/crypto.js
index 08afcfeb..1cfd6642 100644
--- a/test/crypto/crypto.js
+++ b/test/crypto/crypto.js
@@ -80,7 +80,7 @@ describe('API functional testing', function() {
                   0x51,0xe0,0x22,0xf0,0xff,0xa7,0x42,0xd4,0xde,0x0b,0x47,0x8f,0x2b,
                   0xf5,0x4d,0x04,0x32,0x91,0x89,0x4b,0x0e,0x05,0x8d,0x70,0xf9,0xbb,
                   0xe7,0xd6,0x76,0xea,0x0e,0x1a,0x90,0x30,0xf5,0x98,0x01,0xc5,0x73])];
-  
+
   var DSApubMPIstrs = [
     new Uint8Array([0x08,0x00,0xa8,0x85,0x5c,0x28,0x05,0x94,0x03,0xbe,0x07,0x6c,0x13,0x3e,0x65,
                   0xfb,0xb5,0xe1,0x99,0x7c,0xfa,0x84,0xe3,0xac,0x47,0xa5,0xc4,0x46,0xd8,0x5f,
@@ -143,7 +143,7 @@ describe('API functional testing', function() {
     new Uint8Array([0x01,0x00,0x9b,0x58,0xa8,0xf4,0x04,0xb1,0xd5,0x14,0x09,0xe1,0xe1,0xa1,0x8a,
                   0x0b,0xa3,0xc3,0xa3,0x66,0xaa,0x27,0x99,0x50,0x1c,0x4d,0xba,0x24,0xee,0xdf,
                   0xdf,0xb8,0x8e,0x8e])];
-            
+
   var ElgamalpubMPIstrs = [
     new Uint8Array([0x08,0x00,0xea,0xcc,0xbe,0xe2,0xe4,0x5a,0x51,0x18,0x93,0xa1,0x12,0x2f,0x00,
                   0x99,0x42,0xd8,0x5c,0x1c,0x2f,0xb6,0x3c,0xd9,0x94,0x61,0xb4,0x55,0x8d,0x4e,
@@ -200,13 +200,13 @@ describe('API functional testing', function() {
     RSAsecMPIs[i] = new openpgp.MPI();
     RSAsecMPIs[i].read(RSAsecMPIstrs[i]);
   }
-    
+
   var DSAsecMPIs = [];
   for (i = 0; i < 1; i++) {
     DSAsecMPIs[i] = new openpgp.MPI();
     DSAsecMPIs[i].read(DSAsecMPIstrs[i]);
   }
-    
+
   var DSApubMPIs = [];
   for (i = 0; i < 4; i++) {
     DSApubMPIs[i] = new openpgp.MPI();
@@ -217,7 +217,7 @@ describe('API functional testing', function() {
     ElgamalsecMPIs[i] = new openpgp.MPI();
     ElgamalsecMPIs[i].read(ElgamalsecMPIstrs[i]);
   }
-    
+
   var ElgamalpubMPIs = [];
   for (i = 0; i < 3; i++) {
     ElgamalpubMPIs[i] = new openpgp.MPI();
@@ -287,6 +287,25 @@ describe('API functional testing', function() {
       });
     }
 
+    function testAESGCM(plaintext) {
+      symmAlgos.forEach(function(algo) {
+        if(algo.substr(0,3) === 'aes') {
+          it(algo, function(done) {
+            var key = openpgp.crypto.generateSessionKey(algo);
+            var iv = openpgp.crypto.random.getRandomValues(new Uint8Array(openpgp.crypto.gcm.ivLength));
+
+            openpgp.crypto.gcm.encrypt(algo, util.str2Uint8Array(plaintext), key, iv).then(function(ciphertext) {
+              return openpgp.crypto.gcm.decrypt(algo, ciphertext, key, iv);
+            }).then(function(decrypted) {
+              var decryptedStr = util.Uint8Array2str(decrypted);
+              expect(decryptedStr).to.equal(plaintext);
+              done();
+            });
+          });
+        }
+      });
+    }
+
     it("Symmetric with OpenPGP CFB resync", function () {
       testCFB("hello", true);
       testCFB("1234567", true);
@@ -301,11 +320,37 @@ describe('API functional testing', function() {
       testCFB("12345678901234567890123456789012345678901234567890", false);
     });
 
-    it("asmCrypto AES without OpenPGP CFB resync", function () {
-      testCFB("hello");
-      testCFB("1234567");
-      testCFB("foobarfoobar1234567890");
-      testCFB("12345678901234567890123456789012345678901234567890");
+    it.skip("asmCrypto AES without OpenPGP CFB resync", function () {
+      testAESCFB("hello");
+      testAESCFB("1234567");
+      testAESCFB("foobarfoobar1234567890");
+      testAESCFB("12345678901234567890123456789012345678901234567890");
+    });
+
+    describe('Symmetric AES-GCM (native)', function() {
+      var useNativeVal;
+      beforeEach(function() {
+        useNativeVal = openpgp.config.useNative;
+        openpgp.config.useNative = true;
+      });
+      afterEach(function() {
+        openpgp.config.useNative = useNativeVal;
+      });
+
+      testAESGCM("12345678901234567890123456789012345678901234567890");
+    });
+
+    describe('Symmetric AES-GCM (asm.js fallback)', function() {
+      var useNativeVal;
+      beforeEach(function() {
+        useNativeVal = openpgp.config.useNative;
+        openpgp.config.useNative = false;
+      });
+      afterEach(function() {
+        openpgp.config.useNative = useNativeVal;
+      });
+
+      testAESGCM("12345678901234567890123456789012345678901234567890");
     });
 
     it('Asymmetric using RSA with eme_pkcs1 padding', function (done) {