diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,7 +1,12 @@
+## 0.1.21
+
+- Workaround for 0s paddings.
+- Another bug fix for packing Fin.
+
 ## 0.1.20
 
-- bug fix for packing Fin
-- proper handling for MAX_STREAM_DATA
+- Bug fix for packing Fin.
+- Proper handling for MAX_STREAM_DATA
 - util/{client,server} are now called util/{quic-client, quic-server}.
 - Renaming two command options for util/quic-client.
 - Supporting multiple targets in util/quic-client.
diff --git a/Network/QUIC/Client/Reader.hs b/Network/QUIC/Client/Reader.hs
--- a/Network/QUIC/Client/Reader.hs
+++ b/Network/QUIC/Client/Reader.hs
@@ -47,11 +47,11 @@
             Nothing -> close cs0
             Just bs -> do
                 now <- getTimeMicrosecond
-                pkts <- decodePackets bs
+                pkts <- decodePackets bs False
                 mapM_ (putQ now) pkts
                 loop
     logAction msg = connDebugLog conn ("debug: readerClient: " <> msg)
-    putQ _ (PacketIB BrokenPacket) = return ()
+    putQ _ (PacketIB BrokenPacket _) = return ()
     putQ t (PacketIV pkt@(VersionNegotiationPacket dCID sCID peerVers)) = do
         qlogReceived conn pkt t
         myVerInfo <- getVersionInfo conn
diff --git a/Network/QUIC/Packet/Decode.hs b/Network/QUIC/Packet/Decode.hs
--- a/Network/QUIC/Packet/Decode.hs
+++ b/Network/QUIC/Packet/Decode.hs
@@ -18,31 +18,42 @@
 ----------------------------------------------------------------
 
 -- Server uses this.
-decodeCryptPackets :: ByteString -> IO [(CryptPacket, EncryptionLevel, Int)]
-decodeCryptPackets bs0 = unwrap <$> decodePackets bs0
+decodeCryptPackets
+    :: ByteString -> Bool -> IO [(CryptPacket, EncryptionLevel, Int)]
+decodeCryptPackets bs0 checkQuicBit = unwrap <$> decodePackets bs0 checkQuicBit
   where
-    unwrap (PacketIC c l s : xs) = (c, l, s) : unwrap xs
+    unwrap (PacketIC c l s : xs) = loop (c, l, s) xs
     unwrap (_ : xs) = unwrap xs
     unwrap [] = []
+    loop p (PacketIC c l s : xs) = p : loop (c, l, s) xs
+    -- For anti-amplification, adding the length of broken packets
+    -- as if it is pddings.
+    loop (c, l, s) (PacketIB BrokenPacket siz : xs) = loop (c, l, s + siz) xs
+    loop p (_ : xs) = loop p xs
+    loop p [] = [p]
 
 -- Client uses this.
-decodePackets :: ByteString -> IO [PacketI]
-decodePackets bs0 = loop bs0 id
+decodePackets :: ByteString -> Bool -> IO [PacketI]
+decodePackets bs0 checkQuicBit = loop bs0 id
   where
     loop "" build = return $ build [] -- fixme
     loop bs build = do
-        (pkt, rest) <- decodePacket bs
+        (pkt, rest) <- decodePacket bs checkQuicBit
         loop rest (build . (pkt :))
 
-decodePacket :: ByteString -> IO (PacketI, ByteString)
-decodePacket bs = E.handle handler $ withReadBuffer bs $ \rbuf -> do
+decodePacket :: ByteString -> Bool -> IO (PacketI, ByteString)
+decodePacket bs checkQuicBit = E.handle handler $ withReadBuffer bs $ \rbuf -> do
     save rbuf
     proFlags <- Flags <$> read8 rbuf
-    let short = isShort proFlags
-    pkt <- decode rbuf proFlags short
-    siz <- savingSize rbuf
-    let rest = BS.drop siz bs
-    return (pkt, rest)
+    if checkQuicBit && not (isQuic proFlags)
+        then
+            return (PacketIB BrokenPacket len, "")
+        else do
+            let short = isShort proFlags
+            pkt <- decode rbuf proFlags short
+            siz <- savingSize rbuf
+            let rest = BS.drop siz bs
+            return (pkt, rest)
   where
     decode rbuf _proFlags True = do
         header <- Short . makeCID <$> extractShortByteString rbuf myCIDLength
@@ -74,7 +85,8 @@
                     crypt <- CryptPacket header <$> makeLongCrypt bs rbuf
                     siz <- savingSize rbuf
                     return $ PacketIC crypt HandshakeLevel siz
-    handler BufferOverrun = return (PacketIB BrokenPacket, "")
+    handler BufferOverrun = return (PacketIB BrokenPacket len, "")
+    len = BS.length bs
 
 makeShortCrypt :: ByteString -> ReadBuffer -> IO Crypt
 makeShortCrypt bs rbuf = do
diff --git a/Network/QUIC/Packet/Header.hs b/Network/QUIC/Packet/Header.hs
--- a/Network/QUIC/Packet/Header.hs
+++ b/Network/QUIC/Packet/Header.hs
@@ -3,6 +3,7 @@
 module Network.QUIC.Packet.Header (
     isLong,
     isShort,
+    isQuic,
     protectFlags,
     unprotectFlags,
     encodeLongHeaderFlags,
@@ -24,6 +25,10 @@
 {-# INLINE isShort #-}
 isShort :: Flags Protected -> Bool
 isShort (Flags flags) = not $ testBit flags 7
+
+{-# INLINE isQuic #-}
+isQuic :: Flags Protected -> Bool
+isQuic (Flags flags) = testBit flags 6
 
 ----------------------------------------------------------------
 
diff --git a/Network/QUIC/Sender.hs b/Network/QUIC/Sender.hs
--- a/Network/QUIC/Sender.hs
+++ b/Network/QUIC/Sender.hs
@@ -423,12 +423,12 @@
                                         StreamF _ o d _ -> (o, d)
                                         _ -> error "sendStreamSmall"
                                     frame1 = StreamF sid off (dats ++ dats1) fin1'
-                                    sb1 = if fin1 then (sb . (s1 :)) else sb
+                                    sb1 = if fin1' then (sb . (s1 :)) else sb
                                 loop s1 frame1 total1 build sb1
                             else do
                                 let frame1 = StreamF sid1 off1 dats1 fin1'
                                     build1 = build . (frame :)
-                                    sb1 = if fin1 then (sb . (s1 :)) else sb
+                                    sb1 = if fin1' then (sb . (s1 :)) else sb
                                 loop s1 frame1 total1 build1 sb1
                     else return (build [frame], sb [])
 
diff --git a/Network/QUIC/Server/Reader.hs b/Network/QUIC/Server/Reader.hs
--- a/Network/QUIC/Server/Reader.hs
+++ b/Network/QUIC/Server/Reader.hs
@@ -156,7 +156,7 @@
         (bs, peersa) <- safeRecv $ UDP.recvFrom mysock
         now <- getTimeMicrosecond
         let send' b = UDP.sendTo mysock b peersa
-        cpckts <- decodeCryptPackets bs
+        cpckts <- decodeCryptPackets bs True
         let bytes = BS.length bs
             switch = dispatch d conf logAction mysock peersa send' bytes now
         mapM_ switch cpckts
@@ -371,7 +371,8 @@
           Nothing -> UDP.close us
           Just bs -> do
               now <- getTimeMicrosecond
-              pkts <- decodeCryptPackets bs
+              quicBit <- greaseQuicBit <$> getPeerParameters conn
+              pkts <- decodeCryptPackets bs (not quicBit)
               mapM_ (\(p,l,siz) -> writeRecvQ (connRecvQ conn) (mkReceivedPacket p now siz l)) pkts
               loop
     logAction msg = connDebugLog conn ("debug: readerServer: " <> msg)
diff --git a/Network/QUIC/Types/Packet.hs b/Network/QUIC/Types/Packet.hs
--- a/Network/QUIC/Types/Packet.hs
+++ b/Network/QUIC/Types/Packet.hs
@@ -75,7 +75,7 @@
     = PacketIV VersionNegotiationPacket
     | PacketIR RetryPacket
     | PacketIC CryptPacket EncryptionLevel Int
-    | PacketIB BrokenPacket
+    | PacketIB BrokenPacket Int
     deriving (Eq, Show)
 
 -- Not used internally. Only for 'encodePacket'.
diff --git a/quic.cabal b/quic.cabal
--- a/quic.cabal
+++ b/quic.cabal
@@ -1,6 +1,6 @@
 cabal-version:      >=1.10
 name:               quic
-version:            0.1.20
+version:            0.1.21
 license:            BSD3
 license-file:       LICENSE
 maintainer:         kazu@iij.ad.jp
@@ -131,7 +131,7 @@
         bytestring >= 0.10,
         containers >= 0.6 && < 0.7,
         crypto-token >= 0.1.1 && < 0.2,
-        crypton >= 0.34 && < 0.35,
+        crypton >= 0.34,
         memory >= 0.18.0 && < 0.19,
         crypton-x509 >= 1.7.6 && < 1.8,
         crypton-x509-system >= 1.6.7 && < 1.7,
diff --git a/test/PacketSpec.hs b/test/PacketSpec.hs
--- a/test/PacketSpec.hs
+++ b/test/PacketSpec.hs
@@ -87,7 +87,7 @@
 checkBinary :: (Connection, Connection) -> PacketNumber -> ByteString -> IO ()
 checkBinary (senderConn, recverConn) pn bin = do
     ---- Decoding by the receiver
-    (PacketIC (CryptPacket header crypt) lvl _, _) <- decodePacket bin
+    (PacketIC (CryptPacket header crypt) lvl _, _) <- decodePacket bin True
     ---- Cecrypting by the receiver
     Just plain <- decryptCrypt recverConn crypt lvl
     ---- Checking
@@ -97,7 +97,7 @@
     bin' <- BS.createAndTrim 4096 $ \buf ->
         fst <$> encodePlainPacket senderConn (SizedBuffer buf 2048) ppkt Nothing
     ---- Decoding by the receiver again
-    (PacketIC (CryptPacket header' crypt') lvl' _, _) <- decodePacket bin'
+    (PacketIC (CryptPacket header' crypt') lvl' _, _) <- decodePacket bin' True
     ---- Cecrypting by the receiver again
     Just plain' <- decryptCrypt recverConn crypt' lvl'
     ---- Checking
diff --git a/test/TLSSpec.hs b/test/TLSSpec.hs
--- a/test/TLSSpec.hs
+++ b/test/TLSSpec.hs
@@ -135,7 +135,7 @@
         it "describes the examples of Retry" $ do
             let wire0 =
                     dec16 "ff000000010008f067a5502a4262b5746f6b656e04a265ba2eff4d829058fb3f0f2496ba"
-            (ipkt, rest) <- decodePacket wire0
+            (ipkt, rest) <- decodePacket wire0 True
             rest `shouldBe` ""
             case ipkt of
                 PacketIR retrypkt -> do
@@ -259,7 +259,7 @@
         it "describes the examples of Retry" $ do
             let wire0 =
                     dec16 "cf6b3343cf0008f067a5502a4262b5746f6b656ec8646ce8bfe33952d955543665dcc7b6"
-            (ipkt, rest) <- decodePacket wire0
+            (ipkt, rest) <- decodePacket wire0 True
             rest `shouldBe` ""
             case ipkt of
                 PacketIR retrypkt -> do
