What is the GnuPG process for going from a passphrase to a symmetric key? Suppose I use GnuPG to symmetrically encrypt a file like so:

gpg --no-options -c --cipher-algo AES256 --no-random-seed-file -o my.out my.file


I then provide a passphrase when prompted.


What steps does the software actually take to get from the passphrase I provide as a user, to the actual 256-bit AES key which is used to secure the data?
What data relating to or derived from the passphrase is stored in the output ciphertext file?
What of the above is guaranteed by the standard, and what is implementation-defined?
GPG implements the OpenPGP standard RFC 4880, so it implements the String-to-Key Specifiers. 


  3.7.  String-to-Key (S2K) Specifiers
  
  String-to-key (S2K) specifiers are used to convert passphrase
  strings    into symmetric-key encryption/decryption keys.  They are
  used in two    places, currently: to encrypt the secret part of
  private keys in the    private keyring, and to convert passphrases to
  encryption keys for    symmetrically encrypted messages.
  
  3.7.1.  String-to-Key (S2K) Specifier Types
  
  There are three types of S2K specifiers currently supported, and
  some reserved values:

   ID          S2K Type
   --          --------
   0           Simple S2K
   1           Salted S2K
   2           Reserved value
   3           Iterated and Salted S2K
   100 to 110  Private/Experimental S2K



I wrote my own implementation of OpenPGP a while back, if you dont want to search through the GPG source code. If I remember correctly, while decrypting test data I generated with GPG, I found that by default, GPG uses Iterated and Salted S2K (S2K3).

std::string S2K3::run(std::string pass, unsigned int sym_len){
    // get string to hash
    std::string to_hash = "";
    while (to_hash.size() &lt; coded_count(count)){// coded count is count of bytes, not interations
        to_hash += salt + pass;
    }
    to_hash = to_hash.substr(0, coded_count(count));
    // hash string
    std::string out = "";
    unsigned int context = 0;
    while (out.size() &lt; sym_len){
        out += use_hash(hash, std::string(context++, 0) + to_hash);
    }
    return out.substr(0, sym_len);
}


As for your second and third questions, I don't know. I would hope that no information of the password is stored in the file. I have tried to read the GPG source code, but failed doing so. It is very large and complex.